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

从汇编调用printf打印浮点数时出现段错误的技术咨询

Segmentation Fault When Calling printf to Print Float from Assembly Code

看起来你在汇编调用C函数打印浮点数时踩了x86-64调用约定的坑,段错误的原因主要集中在栈对齐问题、参数传递错误和函数实现缺失这几个点上,我来帮你一步步解决:

核心问题拆解

1. 栈没按x86-64 ABI要求对齐

在Linux/macOS等主流平台采用的x86-64 System V调用约定里,调用任何函数前,栈指针rsp必须保持16字节对齐。你写的sub rsp, 55中,55不是16的倍数,直接破坏了栈对齐规则,调用printFloat时自然触发段错误。

2. 浮点数参数没正确传递

x86-64下,浮点数参数是通过XMM系列寄存器传递的——calculateRoot接收的double参数存在XMM0里,但你调用printFloat时根本没把这个参数传过去,而且printFloat的声明也没明确要接收浮点数,这必然导致运行时访问非法内存。

3. printFloat的实现缺失

你的C代码只声明了printFloat,但没写具体实现,链接后运行时会出现未定义行为,这也是段错误的潜在诱因。

修复后的完整代码

补全后的C代码

先把printFloat的实现写对,让它能正确接收double参数并调用printf:

#include <stdio.h>

// 正确实现printFloat,接收double类型参数
void printFloat(double num) {
    printf("The value is: %f\n", num);
}

extern void calculateRoot(double num);

int main() {
    double num = 43432432.235;
    calculateRoot(num);
    return 0;
}

修正后的汇编代码

解决栈对齐问题,同时正确传递浮点数参数:

section .text
global calculateRoot
extern printFloat

calculateRoot:
    push rbp                    ; 保存原基址指针
    mov rbp, rsp                ; 设置新的基址指针,绑定栈帧
    sub rsp, 16                 ; 分配16字节栈空间,确保栈16字节对齐(必须是16的倍数)
    
    ; calculateRoot的参数存在XMM0里,直接调用printFloat即可——
    ; x86-64下第一个浮点数参数就是用XMM0传递的,完美匹配
    call printFloat
    
    mov rsp, rbp                ; 回收栈空间
    pop rbp                     ; 恢复原基址指针
    ret

关键细节说明

  • 栈对齐的逻辑:进入calculateRoot后,push rbp会让rsp减8,此时rsp是8字节偏移(调用者调用calculateRoot前rsp是16对齐的,call指令压入返回地址又减8,所以刚进入函数时rsp是未对齐的)。sub rsp,16后,rsp相对于rbp的偏移是24,调用printFloat前rsp就回到了16对齐的状态(call指令压入返回地址后会再减8,刚好是16的倍数)。
  • 浮点数传递规则:x86-64下前8个浮点数参数用XMM0到XMM7传递,calculateRoot的参数本来就在XMM0里,直接调用printFloat就能把参数传过去,不用额外操作。
  • 调用约定一致性:C和汇编代码默认都遵循System V ABI,只要按规则来就不会出问题。

编译运行命令

假设汇编文件叫root.asm,C文件叫main.c,用下面的命令编译运行:

# 汇编编译成目标文件
nasm -f elf64 root.asm -o root.o
# C代码编译成目标文件
gcc -c main.c -o main.o
# 链接生成可执行文件
gcc main.o root.o -o calc_root
# 运行程序
./calc_root

这样就能正常打印浮点数,不会再出现段错误啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:34:10