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

NASM elf64汇编调用C函数传参时触发SIGFPE错误

问题根因

你遇到的SIGFPE(除零错误)本质是64位汇编调用C函数时违反了平台调用约定,具体问题点如下:

  • 传参方式完全错误:x86_64 Linux ELF遵循System V AMD64调用约定,C函数的前6个整数参数不通过栈传递,而是依次存入rdi、rsi、rdx、rcx、r8、r9寄存器。你把参数9压栈的操作不会被le_sqrt识别,函数读取参数a时会直接取edi寄存器里的随机残留值,一旦这个值为0,执行number/n的除法指令时就会触发除零异常,抛出SIGFPE。这也是你把a直接写在函数内部时程序能正常运行的原因——此时不需要从外部寄存器读参数,不会拿到垃圾值。
  • exit系统调用参数寄存器用错:64位Linux的60号exit系统调用,退出码参数需要放在rdi寄存器,你写的mov rsi,0是无效的,会导致进程退出码不符合预期。
  • 栈对齐不符合要求:64位环境下调用C函数前,栈指针rsp必须保持16字节对齐。程序进入_start入口时栈天然是16字节对齐的,你额外push一个8字节的rbp后栈就变成8字节错位,再执行call指令压入8字节返回地址,进入le_sqrt时栈就不符合对齐要求,可能触发其他隐性崩溃。
修正后的汇编代码
bits 64
global _start
extern le_sqrt 

_start:
    mov rdi, 9  ; 第一个int参数按约定存入rdi,不需要压栈
    call le_sqrt ; 调用C函数,返回值默认存在rax中

    mov rax, 60 ; exit系统调用号
    mov rdi, 0  ; 退出码存入rdi,如果要使用sqrt计算结果作为退出码,改成mov rdi, rax即可
    syscall

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:54:23