2017-04-27 96 views
2

比較單字(2字節)時,我遇到CMP指令的問題。
以下是我main.asm中x86 CMP指令不適用於單字比較

[org 0x7c00] 

mov bx, HELLO_MSG 
call print_string 

mov bx, GOODBYE_MSG 
call print_string 

jmp $ 

%include "print_string.asm" 

; Data 
HELLO_MSG: 
    db 'Hello, World!', 0 
GOODBYE_MSG: 
    db 'Goodbye!', 0 

這是print_string.asm文件:

print_string: 
    pusha 
    mov ah, 0x0e 
    loop: 
     call print_char 
     cmp word [bx], 0 
     jne loop 
    popa 
    ret 

print_char: 
    mov al, [bx] 
    int 0x10 
    add bx, 1 
    ret 

此代碼打印出以下幾點:

你好世界!再見!再見!

我知道,當我在HELLO_MSGGOODBYE_MSG之間添加

db 0 

,如預期的代碼將工作。任何人都可以解釋爲什麼CMP只有在字符串之間有4個字節爲0時才能工作?

如果有人有興趣看編譯的輸出,那就是:

bb 23 7c e8 08 00 bb 31 7c e8 02 00 eb fe 60 b4 
0e e8 07 00 83 3f 00 75 f8 61 c3 8a 07 cd 10 83   
c3 01 c3 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 
00 47 6f 6f 64 62 79 65 21 00 00 00 00 00 00 00   
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
*   
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa 

55 aa末是由我添加,因爲我使用此代碼作爲引導裝載程序。

+5

你正在做'cmp word [bx],0',它比較從地址'bx'開始的2個字節。您可能想要比較單個字節。 'cmp byte [bx],0' –

+0

我也建議你正確設置段寄存器和堆棧等。我在這個Stackoverflow答案中提供了一些提示[一般引導程序提示](http://stackoverflow.com/a/ 32705076/3857942) –

+1

您可能還希望爲'print_string'使用_BX_以外的寄存器。 [_Int 10/AH = 0Eh_](http://www.ctyme.com/intr/rb-0106.htm)使用_BH_作爲要寫入的頁碼。您可能希望將其設置爲0.這意味着您應該使用_BX_以外的寄存器作爲字符串指針。也許_SI_。 –

回答

3

CMP指令不適用於單字比較的原因是因爲一個字必須包含2個字節。由於編譯輸出顯示,有兩條消息之間只有1個字節,你需要將CMP指令的大小從文字變成字節:

cmp byte [bx], 0 

我做了假設編譯輸出格式的錯誤通過2.佈置在字節然而,隨着通過邁克爾佩奇以下注釋的幫助下:

線4點開始以00 47 6F這些值中的每一個(用空格隔開)是單字節,而不是2字節。 00是0的單個字節,而不是兩個字節的0

我能夠意識到我的錯誤。

+0

for1從您的錯誤中學習並回答您自己的問題 –