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

从NASM向C传递命令行参数时触发段错误,求技术解决方案

问题分析与解决建议

核心问题根源

你遇到的段错误完全是因为违反了x86-64 Linux的System V AMD64调用约定,具体问题点:

  1. 参数传递方式错误:x86-64下前6个整数/指针参数是通过寄存器传递的,而非栈。argc需要放在RDI,argv需要放在RSI,你的代码直接调用函数,函数会去寄存器找参数,自然读取到非法值导致访问错误。
  2. 栈对齐要求未满足:调用C函数前,栈指针RSP必须处于16n + 8的位置(call指令会压入8字节返回地址,确保进入函数后RSP是16字节对齐,这是ABI强制要求),而_start被内核初始化时RSP是16字节对齐的,直接调用会破坏对齐规则,触发内存访问异常。
  3. _start不是普通函数:它没有调用者,不能用ret返回,必须通过exit系统调用或函数终止程序。

修正后的汇编代码

extern func
extern exit

section .text
_start:
    ; 从内核初始化的栈中读取argc和argv,放入调用约定要求的寄存器
    mov rdi, [rsp]        ; 第一个参数:argc -> RDI
    mov rsi, [rsp + 8]    ; 第二个参数:argv -> RSI

    ; 调整栈对齐:内核启动时RSP是16字节对齐,sub rsp,8后变为16n+8,call后RSP为16n(符合函数入口对齐要求)
    sub rsp, 8

    ; 调用C函数
    call func

    ; 函数返回后,调用exit结束程序(_start不能用ret返回)
    mov rdi, 0            ; 退出码设为0
    call exit

额外注意事项

  • 如果你的struct of_my_creation大小超过16字节,x86-64调用约定会要求调用者提前分配返回结构的空间,并将指针作为第一个参数传递(此时argc会变为第二个参数,对应RSI,argv对应RDX),需要根据结构体大小调整参数传递逻辑。
  • 编译链接命令示例:
    nasm -f elf64 your_asm.s -o your_asm.o
    gcc -c your_c.c -o your_c.o
    gcc your_asm.o your_c.o -o your_program
    

内容的提问来源于stack exchange,提问作者R-Rothrock

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:09:58