我是一名初学者,出于某种原因,插入和弹出堆栈对我来说不起作用。我的引导加载程序:
org 0x7c00
bits 16
jmp main
print:
pop bx
mov al, [bx]
mov ah, 0eh
int 10h
ret
main:
mov bx, msg
push bx
call print
cli
hlt
msg: db 'Hello World!', 0
times 510 - ($-$$) db 0
dw 0xAA55
我认为,这应该做的是推送地址 msg
从bx
入栈然后将其检索到 bx
。然而,情况似乎并非如此。 'H'
没有被打印。一个'-'
而是打印出来。如果我使用 msg
就可以了作为有效地址。
编辑:正如邓肯指出的那样,call
指令将返回地址压入堆栈顶部,这使得上述程序使用该返回地址进行 BIOS 中断!我现在pop
返回地址为 dx
然后pop
进入bx
,使用 bx
的值和jmp
至dx
完成后!
org 0x7c00
bits 16
jmp main
print:
pop dx
pop bx
mov al, [bx]
mov ah, 0eh
int 10h
jmp dx
main:
mov bx, msg
push bx
call print
cli
hlt
msg: db 'Hello World!', 0
times 510 - ($-$$) db 0
dw 0xAA55
最佳答案
call
指令将程序计数器压入堆栈,ret
从堆栈中弹出顶部值并跳转到该处。
因此,您不能通过在调用之前推送参数并在调用中弹出参数来将参数传递给函数,因为保存的 pc 会妨碍。
选项可能包括设置一个帧指针,以便您可以访问仍在堆栈上的参数,然后将它们作为返回的一部分弹出。
或者对于这么简单的事情,您可以将返回地址弹出到另一个寄存器中,而不是返回,而是跳转到它。
关于程序集 8086-从堆栈中插入和弹出寄存器不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45564831/