x86 CMP指令不适用于单个字比较

时间:2017-04-27 01:25:37

标签: assembly x86 x86-16 qemu bootloader

在比较单个单词(2个字节)时,我遇到了CMP指令的麻烦 以下是我的 main.asm

[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 World!再见!再见!

我知道当我添加

db 0

HELLO_MSG GOODBYE_MSG 之间,代码将按预期工作。任何人都可以解释为什么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由我添加,因为我使用此代码作为启动加载程序。

1 个答案:

答案 0 :(得分:3)

CMP指令不能用于单字比较的原因是一个字必须包含2个字节。由于编译后的输出显示两条消息之间只有1个字节,因此需要将CMP指令的大小从一个字改为另一个字节:

cmp byte [bx], 0

我错误地认为编译的输出格式将字节排列为2.但是,在Michael Petch的以下评论的帮助下:

  

第4行以00 47 6f开始。这些值中的每一个(用空格分隔)是单个字节,而不是2个字节。 00是0的单字节,而不是0的两个字节

我能够意识到自己的错误。