You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bootloader栈操作问题求助:push/pop导致打印异常原因解析

为什么Bootloader里的push+call+pop栈操作会导致乱码?

核心原因:忽略了call指令的自动栈行为

x86实模式下,call指令执行时会自动把当前指令的下一条指令地址(返回地址)压入栈,再跳转到目标函数。你的代码没考虑这个机制,导致pop bx拿到的不是字符串地址,而是返回地址,最终打印指令字节出现乱码。

代码栈流程拆解

咱们一步步捋栈的变化:

  1. 栈初始化:mov bp, 0x7c00、mov sp, bp,此时栈顶指针sp指向0x7c00(实模式栈向下生长,压栈时sp会递减)。
  2. 压入字符串地址:push message把message的16位地址压栈,sp减2变为0x7BFE,栈顶现在是message的地址。
  3. 执行call指令:call printstring触发CPU先把call指令的下一条指令地址(也就是printstring标签的起始地址)压入栈,sp再减2变为0x7BFC,栈顶换成了这个返回地址。

printstring函数的错误操作

进入printstring后,第一条指令pop bx弹出的是栈顶的返回地址,而非你预期的message地址:

  • 后续用mov al, [bx]取的是printstring函数第一条指令的机器码(pop bx对应字节0x5B),调用int 0x10打印自然是乱码。
  • 最后执行ret时,会弹出栈里剩下的message地址作为返回地址,CPU跳转到字符串内存执行,这属于非法指令操作,会引发后续错误。

正确的传参方式参考

如果要传递字符串地址,更稳妥的方式是直接用寄存器:

mov bx, message
call printstring

如果一定要用栈传参,应该通过基址指针bp访问栈参数:

push message
call printstring

printstring:
    push bp
    mov bp, sp
    mov bx, [bp+2]  ; bp+2的位置是push的message地址,bp位置是返回地址
    ; 打印逻辑...
    pop bp
    ret

内容的提问来源于stack exchange,提问作者jonasbrocas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:45:41