汇编 - 循环结束时的子指令

时间:2012-03-08 18:04:08

标签: assembly x86

我读了一本关于汇编的书,它有下一个代码。代码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,并且会跳到最后。

2 个答案:

答案 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的值设置为零,然后在数组完全匹配时返回。