我读了一本关于汇编的书,它有下一个代码。代码comapre(lexcially)两个数组(int值),如果第一个更大则返回1,如果相等则返回0,否则返回-1:
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
我不明白为什么它需要这一行:sub eax,eax
。如果我们有两个相同的数组,那么在最后的比较中,我们会得到,例如cmp 3,3
- 然后我们将退出循环,而对于行je equal
- 它将返回true,并且会跳到最后。
答案 0 :(得分:2)
设置Z标志,使宏后的je equal
知道两个数组相等。 Z标志将由cmp eax, ebx
设置或清除,如果此时显而易见,控件将转移到done
- 不幸的是,在此之后它立即执行了几个add
s,它(可能)会再次清除Z标志,因此需要sub eax, eax
再次为宏后的条件跳转设置它。
真正的问题是你需要mov eax, 0
equal:
的原因 - 答案是你没有。除了设置Z标志外,sub eax, eax
还将eax设置为0,可以/可以直接返回。即使您因某种原因决定重新加载0值,您可能希望使用sub eax, eax
(或xor eax, eax
)来执行此操作(代码稍微小一点,至少在某些情况下处理器,也更快。)
编辑:我应该补充一点,至少在我看来,这是一个相当糟糕的宏使用。至少,应该有一些注释来指定宏的界面,这可能会在被问到之前回答问题。
答案 1 :(得分:1)
该函数的结果在EAX寄存器中返回。最终sub eax, eax
将EAX的值设置为零,然后在数组完全匹配时返回。