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

x64汇编中函数栈参数双重解引用的合法性与逻辑问询

x64汇编代码疑问解答(Microsoft x64调用约定)

疑问1:lfunc中RBX未按调用约定备份却能运行

Microsoft x64调用约定规定,RBX属于非易失性寄存器,函数使用前必须保存(push到栈)、使用后恢复(pop),以保证调用者的RBX值不受影响。

这段代码能正常运行的原因是:调用者main在调用lfunc后,没有再使用RBX寄存器。即使lfunc修改了RBX,也不会破坏后续逻辑。但这属于不规范的写法,严格遵守调用约定的话,应该在lfunc开头添加push rbx,结尾添加pop rbx。

疑问2:栈参数读取的逻辑与合法性

你这里的核心误解是混淆了变量标签的含义:在汇编中,fourth是一个内存标签,它代表的是存储字符'D'的内存地址,而不是字符'D'的值(0x44)。

栈布局分析

在main调用lfunc前,执行了push fourth等操作,这些push指令压入栈的是各个字符变量的地址(64位,8字节),而不是字符值。进入lfunc后,栈帧的关键布局如下:

  • rbp+8:调用lfunc的返回地址(8字节)
  • rbp+8+8到rbp+8+8+31:32字节的shadow space(Microsoft x64调用约定要求的)
  • rbp+8+8+32:栈上第一个额外参数,也就是fourth的地址(8字节)

所以代码中mov rax, qword [rbp+8+8+32]是正确的:用qword读取是因为x64的地址是64位,栈上每个push的参数都是8字节的地址。之后mov bl,[rax]是从fourth的地址中读取字节,也就是字符'D'的0x44,完全合法,自然能得到正确结果。

你之前误以为压入栈的是0x44,所以才会觉得解引用是垃圾地址,实际上压入的是变量的地址,解引用后就是正确的字符值。

调试问题说明

断点导致调试器挂起大概率是调试环境的问题,比如io64.inc中的代码可能包含调试器不兼容的指令,或者调试器本身的配置问题。建议尝试移除io64.inc后重新编译调试,或者换用其他调试工具测试。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:15:59