4

I have the following disassembly which looks like a buffer being populated with zeros in a loop, however, I'm confused at why the alignment is needed here (if a jump will always be 4-bytes, why does aligning to a 4-byte boundary matter?)

I'm also confused at what and'ing ecx (which presumably contains the size of the buffer plus how many bytes it was misaligned by) with 0xFFFFFFFC does, it's not an address so why is the same and used to 4-byte align something being used on something that is being used as a count for a loop etc.

Could someone give a good walkthrough of what this code is doing and why? Is it really a compiler optimization or handwritten code? Is the intention speed etc?

Disassembly

1
  • 1
    Is this a 32-bit binary? My guess would be that since it is using indirect addressing, you are not guaranteed to have a 4-byte aligned pointer so the compiler aligns it before performing reads/writes to such an address. One interesting thing is the mov ebx, 0 instruction. I thought that most compilers would output an xor ebx, ebx instruction. This could either mean a non-standard compiler was used or maybe it is handwritten. Jan 2, 2020 at 18:04

1 Answer 1

2

You'll find a commented analysis of the assembly code with pseudo-code. What's obvious is that this is 'crappy' compiler generated code used to align local variables to a 4-bytes boundary. Most optimizing compilers avoid using the stack and use registers when optimization flags are set (i.e. gcc -O2, ...).

    lea     eax, [esp+12h]
    mov     ecx, 1Ah
    mov     ebx, 0
    mov     [eax], ebx
    mov     [eax+ecx-4], ebx
    lea     edx, [eax+4]
    and     edx, 0FFFFFFFCh
    sub     eax, edx
    add     ecx, eax
    and     ecx, 0FFFFFFFCh
    and     ecx, 0FFFFFFFCh
    mov     eax, 0

    loc_401500:
    mov     [edx+eax], ebx
    add     eax, 4
    cmp     eax, ecx
    jb      short loc_401500

0xFFFFFFC ==> 11111111111111111111111111111100 in binary. The and operation conserves the bits facing 1s and unsets the ones facing 0s.

    //esp is stack pointer address (suppose esp = 0x00000000)                                                                                                            
    //Calculations are done in base 10                                                                                                                                   

    eax = esp + 18          : eax = @18                             //Store the address located 18 bytes from stack pointer                                              
    ecx = 26                : ecx = 26                              //Number of elements in the array                                                                    
    ebx = 0                 : ebx = 0                               //Zero up                                                                                            
    eax[0] = ebx            : eax[ 0] = 0 (@18)                     //Set eax[ 0]               = 0                                                                      
    eax[ecx - 4] = ebx      : eax[22] = 0 (@18 + 26 - 4 = @40)      //Set eax[26 - 4] = eax[22] = 0                                                                      
    edx = eax + 4           : edx = @22                             //Store the address located 4 bytes from eax (22 bytes from stack pointer)                           
    edx &= 0FFFFFFFCh       : edx = @20                             //Trucate the pointer to a 4 byte boundary (zero up the lower two bits)                              
    eax -= edx              : eax = -2
    ecx += eax              : ecx = 24
    ecx &= 0FFFFFFFCh       : ecx = 24                             //Trucate the pointer to a 4 byte boundary                                                           
    ecx &= 0FFFFFFFCh       : ecx = 24                             //Trucate the pointer to a 4 byte boundary - why again? IDK!                                         
    eax = 0                 : eax = 0

    //Loop over 4 bytes by 4 bytes                                                                                                                                       
    while (eax < ecx)
    {
      edx[eax] = ebx
      eax += 4
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.