2012-03-08 40 views
1

我讀了一本關於彙編的書,它有下一個代碼。代碼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

這是設置Z標誌,因此宏後的je equal將知道這兩個數組是相等的。 Z標誌將由cmp eax, ebx設置或清除,如果此時清楚,控制權將轉移至done--不幸的是,在此之後它立即執行一對add s,這將會(可能)再次清除Z標誌,因此需要sub eax, eax來爲宏後的條件跳轉再次設置它。

真正的問題將是爲什麼你需要mov eax, 0equal: - 答案是,你沒有。除了設置Z標誌之外,sub eax, eax還將eax設置爲0,可以/可以直接返回。即使你因爲某種原因決定重新加載0值,你可能也想使用sub eax, eax(或xor eax, eax)(代碼稍小,至少在某些處理器上也更快)。

編輯:我應該補充一點,至少在我看來,這是一個相當差的宏使用。至少應該有一些評論來指定宏的界面,這可能會在問題出現之前回答這個問題。

1

該函數的結果返回到EAX寄存器中。最後的sub eax, eax在返回之前將EAX的值設置爲零,當數組完全匹配時。

+0

是的,我知道。但爲什麼我們需要這個?如果我們在做cmp eax,ebx,那麼我們得到eax = eax-ebx。但是eax = ebx,並且對於那個eax = 0,也沒有這條線。 – 2012-03-08 18:16:56

+1

它確實將eax設置爲0,但這或多或少是偶然的。如果你看看在哪裏使用了'comp'宏,緊接着它會有一些條件跳轉,這取決於它設置Z標誌,並且忽略在eax中的值。 – 2012-03-08 18:17:35

+1

@AdamSh:'cmp eax,ebx'不會改變'eax'中的值 - 它隻影響標誌。 – 2012-03-08 18:18:41