x86汇编调用factorial子程序时Ret指令触发段错误原因咨询
段错误原因分析
你的代码存在多处致命内存访问错误,最终触发ret指令报错的核心是栈结构被非法操作破坏、返回地址读取异常,具体问题如下:
- 最直接的错误:对立即数做内存解引用
第30行代码cmpb $1, (%rdi)存在严重逻辑错误:你在第26行将8(%rbp)的值(也就是main函数压入的立即数5)赋值给了rdi寄存器,加括号相当于访问地址为0x5的内存空间,这是操作系统禁止用户程序访问的低地址非法区域,直接触发内存访问异常,大概率已经破坏了栈上存储的返回地址,导致ret指令读取到非法地址触发段错误。
修正方法:去掉括号,改为直接比较寄存器的值:cmp $1, %rdi - printf调用参数错误
x86_64架构下printf的第一个参数(rdi寄存器)要求是格式字符串的首地址,你的代码第12行直接将计算得到的整数值赋值给rdi,printf会把这个整数当成内存地址去读取格式串,再次触发非法内存访问。
修正方法:在.data段添加格式串定义,比如fmt: .string "5! = %d\n",调用printf前先将fmt的地址赋值给rdi,计算结果赋值给rsi寄存器。 - 栈操作不匹配,栈帧不平衡
- 你在main函数中
push $5压入的是8字节数据,第12行读取时用了-4(%rbp)仅读取4字节,取值错误,应该改为-8(%rbp) - 调用factorial子程序后没有清理栈上压入的参数,需要在
call factorial后添加add $8, %rsp恢复栈指针,否则栈结构一直处于不平衡状态,后续ret指令会读取到错误的返回地址。
- 你在main函数中
- 注释笔误(不影响运行,建议修正)
第23行的注释写的是epilogue(函数尾声),实际是函数入口的序言,应该改为prologue。
内容的提问来源于stack exchange,提问作者user16806508
相关产品推荐
相关产品推荐

