Search code examples
assemblyx86-64low-level

What does the following assembly code really do?


I am not sure what the following is supposed to do but this is what I got so far.

enter image description here

mov eax, 5       (move 5 into register eax)   
add eax, ebx     (add 5 from eax to 0 from ebx and store in eax)
nop              (no operation)
nop              (no operation)
push ebx         (push 0 onto the hardware stack)
nop              (no operation)
pop ebx          (pop the 0 from off the stack and store in ebx)
call [eax]       (get the 5 from eax)

Solution

  • The corrected description for fragment A is:

    mov eax, 5       ; move 5 into register eax
    add eax, ebx     ; add contents of ebx to eax, changing eax
    nop              ; no operation
    nop              ; no operation
    push ebx         ; push contents of ebx onto the stack
    nop              ; no operation
    pop ebx          ; pop top of the stack into ebx
    call [eax]       ; call the subroutine pointed to at location [eax]
    

    The nop instructions followed by push ebx followed by nop followed by pop ebx again don't change anything (other than leaving the former value of ebx at an available location in stack space). So functionally (although with reduced number of consumed CPU cycles and code space), this is equivalent to:

    mov eax, 5       ; move 5 into register eax
    add eax, ebx     ; add contents of ebx to eax, changing eax
    call [eax]       ; call the subroutine pointed to at location [eax]
    

    Fragment B is:

    mov eax, 5       ; move 5 into register eax
    push ecx         ; push contents of ecx onto the stack
    pop ecx          ; pop top of the stack into ecx
    add eax, ebx     ; add contents of ebx to eax, changing eax
    swap eax, ebx    ; swap the contents of eax and ebx
    swap ebx, eax    ; swap the contents of eax and ebx
    call [eax]       ; call the subroutine pointed to at location [eax]
    nop              ; no operation
    

    Swapping two registers twice in a row has no net effect, other than consuming CPU cycles and code space. So fragment B functionally boils down to:

    mov eax, 5       ; move 5 into register eax
    add eax, ebx     ; add contents of ebx to eax, changing eax
    call [eax]       ; call the subroutine pointed to at location [eax]
    

    Functionally the same as fragment A.