我试图从头开始编写一个简单的操作系统,但是我遇到了一个问题。我写了一个简单的程序,遍历一个字符串并将其打印到屏幕上。
print_string:
pusha
cmp byte[bx], 0
je exit
mov ah, 0x0e
mov al, [bx]
int 0x10
inc bx
jmp print_string
exit:
mov ah, 0x0e
mov al, 13
int 0x10
mov al, 10
int 0x10
popa
ret
我将它包含在主文件中。
[org 0x7c00]
mov bx, hello
call print_string
mov bx, hi
call print_string
jmp $
%include "print_string.s"
hello:
db "Hello, World!",0
hi:
db "This is a test.",0
times 510-($-$$) db 0
dw 0xaa55
但是由于某些原因,不打印Hello, World! This is a test.
,而是打印Hello World!
当我删除pusha
和popa
从print_string。S并将其放在主文件中,如下所示:
[org 0x7c00]
mov bx, hello
pusha
call print_string
popa
mov bx, hi
pusha
call print_string
popa
jmp $
%include "print_string.s"
hello:
db "Hello, World!",0
hi:
db "This is a test.",0
times 510-($-$$) db 0
dw 0xaa55
它工作得很好。为什么?
在循环中调用print_string
,每次迭代都执行pusha
。但是对于多个pusha
,只有一个popa
指令。
每个pusha
指令将堆栈指针向下调整,相应的popa
指令将堆栈指针向上调整。这些指令需要动态平衡,正如@ErikEidt准确指出的那样。
修复(对本地标签使用.label
):
print_string:
pusha
.next_char:
mov al, [bx]
test al, al
jz .exit
mov ah, 0x0e
int 0x10
inc bx
jmp .next_char
.exit:
...