x86 程序集:了解数据库语法

x86 assembly: Understanding db syntax

我刚刚开始学习 x86 汇编,方法是阅读我找到的一本在线书籍:http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf

当我阅读这本书并按照示例进行操作时,我 运行 遇到了一个我无法解决的问题,由于我自己对汇编的无知运行,或者可能是编程一般的。我试图在我的引导扇区程序中构建一些代码,这些代码可以打印以 null 结尾的字符串,但该程序只打印第一个字符。

这是我尝试的一些示例代码 运行:

[org 0x7c00]
    mov bx, Hello
    mov ah, 0x0e
Keep_Printing:
    mov al, [bx]
    cmp al, 0
    je Finished_Printing
    int 0x10
    add bx, 0x0008
    jmp Keep_Printing
Finished_Printing:

    cli
    hlt

Hello:
    db "Hello", 0

times 510-($-$$) db 0       
dw 0xAA55

我在想会发生什么情况是 bx 将包含 Hello 的前两个字母的内存地址,但我不确定当我尝试将那个 16 位寄存器的内容移动到8位的人。当我 运行 它时,它只打印 'H' 所以我猜前 8 位进入 al,其余的被忽略?

在那之后,我希望程序在遍历字符串时不断检查 al 是否为 0,如果不是 0 则打印到屏幕上。我不确定如何迭代通过汇编中的一个字符一个字符的字符串,但我认为既然我有 Hello 的起始地址,我可以继续向 bx 中的内存地址添加 8 位。根据 'H' 之后我在内存中输入的内容,打印的内容会发生变化,但我不确定为什么它不是字符串的其余部分。

我确定我在各个层面上都误解了各种事情,但希望这里有人可以帮助澄清。谢谢!

内存地址在bytes,而不是bits,所以你需要添加1个字节,而不是8位。如您所见,将 8 添加到 BX 将寻址 H 上方的内存 8 bytes,这将是一个 0 字节(因为您指定 times 510-($-$$) db 0 (现在,用 0 字节填充字节 510。

解决方案:将 1 添加到 BX,而不是 8(使用 INC BX 可能会更好 - 更快更短)。

btw: mov al,[bx] 意思是'将 BX 指向的 BYTE(即寄存器 BX 中包含的地址)移动到 AL`

db 表示 define BYTE,而不是 bit

正如用户@Magoo 所说,db 表示 'define byte' 因此要遍历字符串,您需要将指针递增 1 而不是 8。

切勿使用BX作为通过BIOS电传功能输出的文本地址。 BH应该是显示页面参数!!!
在您的代码中它 有效 因为文本 "Hello" 在内存中足够低以至于 BH=0。但这是巧合。

[org 0x7c00]
    mov si, Hello
    mov ah, 0x0e
Keep_Printing:
    mov al, [si]
    cmp al, 0
    je Finished_Printing
    int 0x10
    add si, 1
    jmp Keep_Printing
Finished_Printing:

    cli
    hlt

Hello:
    db "Hello", 0

times 510-($-$$) db 0       
dw 0xAA55