2016-02-28 57 views
2

我們的任務是比較整數值並打印出適當的提示以顯示哪些值更大。比較彙編中的整數值

我在下面做的代碼分別將'i'和'j'初始化爲5和4。目標是比較「變量」而不是數值本身。因此,在這個例子中,我把 '我' 和 'J' 在CMP,而不是5和4

global _main 
extern _printf, _system 

section .text 


_main: 
; clear screen 
    push clr 
    call _system 
    add esp, 4 

;Test prints out i. Successfully does the job. 
    push dword [i]   ; why did it work here and not in *cmp*? 
    push prompt2 
    call _printf  
    add esp, 8 

;compare values and do a conditional jump. 
    CMP dword [i], dword [j]   ; compares values stored in i and j. i and j are base 10 nums. This is where the error appears. 
    JG igreat       ; jumps if i is greater than j. 
    JL jgreat       ; jumps if j is greater than i. 
    JE eks        ; jumps if i and j are equal. 
    ret         ; as a measure, this ends the code. 

    igreat:        ; prints out a prompt if i is greater than j. 
    push dword [j] 
    push dword [i] 
    push ibig 
    call _printf 
    add esp, 16 
    ret 

    jgreat:        ; prints out a prompt if j is greater than i. 
    push dword [i] 
    push dword [j] 
    push jbig 
    call _printf 
    add esp, 16 
    ret 

    eks:        ; prints out a prompt if i is equal to j. 
    push dword [i] 
    push dword [j] 
    push ex 
    call _printf 
    add esp, 16 
    ret 



last:         ; terminates the code 
ret 

section .data 
clr   db "cls",0    
i   dd 5      ; i is initialized to 5 
j   dd 4      ; j is initialized to 4 
prompt2  db "Value is %d",13,10,0 
ibig  db "Test 1. Comparisons: %d is bigger than %d",13,10,0 
jbig  db "Test 2. Comparisons: %d is bigger than %d",13,10,0 
ex   db "Test 3. Comparisons: %d is bigger than %d",13,10,0 

兩個查詢我可能會提高:

  1. CMP DWORD [I] dword [j]產生一個錯誤:操作碼和操作數的無效組合;但是我在前面的調用/代碼行上使用 printf函數成功恢復了值。這是爲什麼?
  2. 我試圖用立即的CMP dword [i],9代替dword [j]。它確實打印出正確的提示,但卻使程序沒有響應。這是爲什麼?

請注意,我正在運行Windows 8 Intel 32位,此代碼已在DoSBox中運行的NASM和CMD中的GCC中「編譯」。

我是一個初學者,任何幫助將不勝感激。謝謝!

+0

'前'應該說,'平等'。 – philipxy

+2

'CMP'只能有寄存器和立即數,寄存器和寄存器,寄存器和存儲器或存儲器和立即數。它無法比較兩個存儲位置,所以錯誤是正確的。至於「沒有迴應」,我認爲你的'ESP'壞了。你爲什麼要添加16個?爲什麼不存儲到'EBP'中並最終恢復? –

回答

6

CMP無法比較兩個內存位置。它可以將寄存器與寄存器,常量或存儲器進行比較,並且可以將存儲器位置與常數或寄存器進行比較。這就是爲什麼你得到一個錯誤,這是正確的。您必須將其中一個值存入寄存器然後進行比較。

程序「無響應」的原因是因爲你搞砸了ESP。你推動堆棧,調用_printf,然後由於某種原因將ESP移動16個字節。然後RET將跳轉到堆棧中的第一個值,我相信這是不正確的。

您應該ESP值存儲到EBP在啓動和恢復回報和ESP然後RET

+0

我想ESP的問題是由於混合調用約定。 – zx485