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

32位x86汇编栈局部变量在函数调用后值丢失问题咨询

问题根因

你遇到的重复打印问题本质是局部变量栈空间未预留,导致存储的字符串地址被后续入栈操作覆盖,具体栈帧逻辑如下:

  • 进入main函数执行pushl %ebp; movl %esp, %ebp后,ebp与esp指向同一位置,你并没有通过subl $N, %esp的操作为局部变量预留栈空间,此时-4(%ebp)对应的内存地址属于未被保留的栈区域。
  • 你执行movl $LC0, -4(%ebp)将world字符串地址写入该位置后,后续执行pushl $LC1操作时,pushl会先将esp减4,正好指向-4(%ebp)的地址,直接把你之前写入的LC0地址覆盖为LC1的地址。
  • 第二次打印时读取-4(%ebp)取到的是被覆盖的LC1地址,自然会重复打印Test Print。

你提到的“赋值后直接打印就正常”也能印证这个根因:赋值后没有其他入栈操作覆盖该地址,取出的自然是正确的LC0地址。

修复方案

只需要在main函数栈帧初始化后,给局部变量预留对应大小的栈空间即可,修改后的main代码如下:

main:
    pushl %ebp
    movl %esp, %ebp
    subl $4, %esp # 新增:为存储在-4(%ebp)的局部变量预留4字节空间
.section .data
LC0:
    .string "world\n"
LC1:
    .string "Test Print\n"
.section .text
    movl $LC0, -4(%ebp)
    pushl $LC1
    call print
    addl $4, %esp # 可选:符合cdecl调用约定,调用者清理入栈参数
    pushl -4(%ebp)
    call print
    addl $4, %esp # 可选:同上清理参数
    leave
    ret

额外优化建议

不要在.text代码段中穿插.section .data声明,建议把所有数据段内容统一放在代码最开头或末尾,避免汇编器处理段切换时出现不可预期的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:18:03