我刚开始学习x86程序集,并附上了我发现的在线图书:http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf
当我阅读这本书并按照这些例子时,我遇到了一个问题,由于我自己对集会的无知,或者一般的编程,我无法解决这个问题。我试图在我的引导扇区程序中构建一些代码,它可以打印一个以空字符结尾的字符串,但程序只打印第一个字符。
以下是我尝试运行的一些示例代码:
[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'之后在内存中击中的内容打印更改,但我不确定为什么它不会是字符串的其余部分。
我确信我在各种层面都误解了各种各样的事情,但希望这里有人可以帮助澄清事情。谢谢!
答案 0 :(得分:0)
内存在bytes
而非bits
中进行寻址,因此您需要添加1个字节,而不是8位。正如您所知,向BX
添加8将解决bytes
之上的内存8 H
,这将是0
字节(因为您指定times 510-($-$$) db 0
(低,用0
字节填充到字节510。
解决方案:将1
添加到BX,而不是8
(可能更好地使用INC BX
- 更快更短)。
btw:mov al,[bx]
表示将BX指向的BYTE(即寄存器BX中包含的地址)移动到AL`
db
表示define BYTE
,而不是bit
答案 1 :(得分:0)
用户@Magoo表示db
表示'定义字节',因此要迭代字符串,需要将指针递增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