I am not sure what the following is supposed to do but this is what I got so far.
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)
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.