I read a book about assembly, which have the next code. The code comapre (lexcially) two arrays (int value), and return 1 if the first is bigger, 0 if it equal or -1 otherwise:
Comprator:
push ebp
mov ebp, esp
mov esi, [ebp+8] ; first - A
mov edi, [ebp+12] ;Second - B
mov ecx, [ebp+16]
comp esi,edi,ecx
jl less
je equal
mov eax, 1
jmp end
equal:
mov eax,0
jmp end
less:
mov eax, -1
jmp end
end:
pop ebp
ret
%macro comp 3
mov ecx, %3
%%l:
mov eax,[%1]
mov ebx,[%2]
cmp eax,ebx
jne %%done
add %1, 4
add %2, 4
loop %%l
sub eax,eax
%%done:
%endmacro
I don’t undestand why it needs the line: sub eax,eax. If we have two identical arrays, so in the last compare, we would get, for example, cmp 3,3 – then we will exit from the loop, and for the line je equal – it will return true, and would jump to end.
It’s to set the Z flag so the
je equalafter the macro will know that the two arrays were equal. The Z flag would be set or cleared by thecmp eax, ebx, and if it’s clear at that point, control will transfer todone— unfortunately, immediately after that it does a couple ofadds, which will (probably) clear the Z flag again, so thesub eax, eaxis needed to set it again for the conditional jumps after the macro.The real question would be why you need the
mov eax, 0atequal:— and the answer is that you don’t. Along with setting the Z flag, thesub eax, eaxalso sets eax to 0, which can/could be returned directly. Even if you did decide to re-load the 0 value for some reason, you probably want to use thesub eax, eax(orxor eax, eax) to do so (the code is a little smaller and at least on some processors, faster as well).Edit: I should add that at least in my opinion, this is a fairly poor use of a macro. At the very least, there should be some comments to specify the macro’s interface, which would probably have answered the question before it was asked.