The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: Gunner on April 27, 2011, 12:22:56 AM

Title: Create buffer divisible by 4
Post by: Gunner on April 27, 2011, 12:22:56 AM
By the time I get to coding, I am tired after a long day so the answer is not coming to me...

How would I create a buffer that is divisible by 4?  Or would this be unnecessary?  I am thinking for alignment that buffers should be divisible by 4 right?

I have variable length strings that I get the lengths of and add em together and create a buffer with HeapAlloc, lets say at one time the length might be 49, is there an equation or some math I could use to figure out it should be made 52? if it is say 56, then we are good to go... etc...
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 12:42:24 AM
        mov     edx,StringLength
        add     edx,4                  ;add 1 for terminator and 3 for mod function
        and     edx,-4                 ;=0FFFFFFFCh
;edx = buffer length


i prefer not to use EAX for these because you get shorter code with any other register
EAX does not have the shortened forms for signed byte add, sub, etc

of course, you can do it with an EQU if the length is known in advance
Title: Re: Create buffer divisible by 4
Post by: Gunner on April 27, 2011, 12:46:16 AM
Nice, just what I was looking for... Thanks!

The lengths aren't known before hand...
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 12:56:25 AM
if you don't count the terminator...

X = (N + M - 1) and (- M)

X = result size
N = minimum size
M = alignment size
Title: Re: Create buffer divisible by 4
Post by: qWord on April 27, 2011, 01:03:19 AM
The memory returned by HeapAlloc() and GlobalAlloc() is allways 8 byte aligned.
Title: Re: Create buffer divisible by 4
Post by: Antariy on April 27, 2011, 02:52:24 AM
Quote from: dedndave on April 27, 2011, 12:42:24 AM
i prefer not to use EAX for these because you get shorter code with any other register
EAX does not have the shortened forms for signed byte add, sub, etc

AFAIK, ML produces short opcode form for the short immediates, i.e., for ADD EAX,4 this would be db 83h,0C0h,04h, and 83h, 0E0h, 0FCh for the AND EAX,-4
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 03:22:34 PM
as usual, you're right, Alex   :P
another bad habit i have to break from the 8086 days
Title: Re: Create buffer divisible by 4
Post by: FORTRANS on April 27, 2011, 04:13:38 PM
Hi,

   It works the same for the 8086.  Abstracted from a TASM
reference.

83 /0 ib   ADD r/m16,imm8    Add a sign-extended immediate
                             byte to r/m word


Regards,

Steve N.
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 04:50:59 PM
huh ?
what the hell am i thinking - lol
i was pretty sure that
        ADD     AX,8
was 3 bytes long
and that
        ADD     DX,8
was 2
now you guys are just picking on me because i am getting old - lol
Title: Re: Create buffer divisible by 4
Post by: mineiro on April 27, 2011, 05:09:36 PM

        mov     edx,StringLength
        and      edx,03h
        jz   align_4
       not dl
       inc dl
       and dl,03h
        add       edx,StringLenght
        align_4:
;edx = buffer length


Title: Re: Create buffer divisible by 4
Post by: FORTRANS on April 27, 2011, 05:30:10 PM
Hi,

   Minor question.  Or brainfart?


       not dl
       inc dl

; Is that not the same result as...

        NEG     DL      ; except for carry flag?


Regards,

Steve
Title: Re: Create buffer divisible by 4
Post by: jj2007 on April 27, 2011, 05:35:17 PM
Me I am so used to the memalign opcode :bg
include \masm32\include\masm32rt.inc

.code
Dummy db 123
txDave db "Hi, Dave!", 0
AppName db "Masm32:", 0

start: mov esi, offset txDave
memalign esi, 4
MsgBox 0, esi, addr AppName, MB_OK
exit

end start
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 05:36:33 PM
        mov     edx,StringLength
        and      edx,03h
        jz   align_4
       not dl
       inc dl
       and dl,03h
        add       edx,StringLenght
        align_4:
;edx = buffer length

       not dl
       inc dl

; Is that not the same result as...

        NEG     DL      ; except for carry flag?

even so - that is a lot of code - ouch !
i like...
       add     edx,3
       and     edx,-4

a lot better
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 05:39:08 PM
memalign macro from masm32   :bg
      memalign MACRO reg, number
        add reg, number - 1
        and reg, -number
      ENDM


at least i got one thing right, today
i feel like my mind is slipping farther and farther every day around you guys

well, i used to be pretty sharp   :lol
i was also good lookin, but i don't remember what that was like, either
Title: Re: Create buffer divisible by 4
Post by: mineiro on April 27, 2011, 06:18:47 PM
Yes, neg works, maybe I need sleep a bit hehehe.

align2 proc len:dword,multiple_of_2:dword
;to do: need check if multiple of 2 is so high to fit in this dword
push ecx
mov     edx,len
mov ecx,multiple_of_2
dec ecx
and      edx,ecx
neg edx
and edx,ecx
add edx,len
pop ecx
ret
align2 endp
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 06:37:13 PM
 :dazzled:
Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 06:40:57 PM
align2 proc len:dword,multiple_of_2:dword
;to do: need check if multiple of 2 is so high to fit in this dword

        mov     edx,multiple_of_2
        mov     eax,len
        add     eax,edx
        dec     eax
        neg     edx
        and     eax,edx
        ret

align2 endp
Title: Re: Create buffer divisible by 4
Post by: mineiro on April 27, 2011, 06:52:59 PM
Fatality, Sr Dedndave wins, flawers victory hehehe.  :thumbu
Title: Re: Create buffer divisible by 4
Post by: drizz on April 27, 2011, 06:59:43 PM
or
mov eax,Value
mov edx,Alignment
dec eax
dec edx
or eax,edx
inc eax


and aligned memory alloc

if @WordSize ne 8
rax equ <eax>
rdx equ <edx>
size_t typedef dword
else
size_t typedef qword
endif

_alloc:
mov rax,_ALLOC_BYTES
add rax,_MEMORY_ALIGN
invoke HeapAlloc,_HHEAP,HEAP_GENERATE_EXCEPTIONS+HEAP_ZERO_MEMORY,rax
mov rdx,rax
add rax,_MEMORY_ALIGN
and rax,-_MEMORY_ALIGN
mov [rax-size_t],rdx
ret

_free:
mov rax,[rax-size_t]
invoke HeapFree,_HHEAP,HEAP_GENERATE_EXCEPTIONS+HEAP_ZERO_MEMORY,rax
ret


Title: Re: Create buffer divisible by 4
Post by: dedndave on April 27, 2011, 07:01:19 PM
sorry, drizz, i don't speak "rax"   :lol
Title: Re: Create buffer divisible by 4
Post by: hutch-- on April 28, 2011, 01:40:49 AM
Rob,

To address your original question, there is no overriding reason to make a buffer divisible by 4. As Erol mentioned allocated memory is already 8 byte aligned and the solution is to simply make your buffer large enough to fit the data you want to put into it. Memory is rarely ever allocated in very small amounts at an OS level so there is no reason why you should have to trim its size down to an arbitrary byte count. Now this means that if you need 15k there is no loss at allocating 16k.

If you need to have memory aligned by greater than 8 bytes, add the extra onto the buffer length then align a location near the beginning of the start address and pass back a pointer to that location. When you deallocate the memory later make sure you deallocate the original memory pointer, not the aligned location. This matters if you want to use later SSE opcodes where they require 16 byte alignment.
Title: Re: Create buffer divisible by 4
Post by: cmpxchg on May 01, 2011, 05:34:19 AM

  dec   eax              ; make sure # is either aligned to lower value or not aligned
  and   eax, -2          ; align down, has no effect if aligned to lower
  add   eax, 2           ; += 2


  number 0, 2byte aligned will result in 0
  number 1, 2byte aligned will result in 2
  number 2, 2byte aligned will result in 2
  number 3, 2byte aligned will result in 4
  number 4 2byte aligned will result in 4
                                                   
Title: Re: Create buffer divisible by 4
Post by: dedndave on May 01, 2011, 11:13:37 AM
why not...
        inc     eax
        and     eax,-2

INC/DEC only works for 2-alignment
larger than that, and you are back to...
        add     eax,M-1
        and     eax,-M