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

x86-64汇编实现func函数运行触发Segmentation fault问题求助

问题排查

以下是导致段错误和逻辑错误的所有问题点:

  • 栈操作错误:64位模式下栈指针寄存器是rsp,你代码末尾栈恢复用了add sp,16,会直接破坏栈结构导致段错误。同时x86-64 System V调用约定要求调用C库函数前栈必须16字节对齐,你开头sub rsp,16后,call指令会压入8字节返回地址,此时栈偏移为8字节,不满足对齐要求。
  • 输入变量定义错误:你需要存储32位有符号int,但是用.word 0定义的var1只有16位长度,scanf输入时会越界覆盖后续内存数据。
  • 外部变量声明错误:A是外部导入的指针,你用.global A是导出符号,应该改为.extern A,同时需要显式声明用到的C库函数scanf、printf。
  • 数组访问逻辑错误:你每次直接读取A指针本身的值参与计算,没有根据循环下标读取数组A的对应元素,完全不符合需求。
  • 乘法逻辑完全错误:
    1. 有符号数相乘需要用imul指令,你用的mul是无符号乘法,结果会出错
    2. mul/imul使用寄存器操作数时,默认源操作数之一是rax,你没有把输入的整数存入rax就直接调用乘法指令
    3. 你代码里乘法后直接加rcx的值,加的是A的指针值,根本不是乘法结果
  • 可变参数函数调用规则错误:调用scanf、printf这类可变参数C函数前,需要将rax清零,标记没有使用向量寄存器传参。
修正后的完整代码
.intel_syntax noprefix
.text
.global func
.extern A
.extern scanf
.extern printf

func:
    # 栈对齐:预留24字节,保证call之前栈16字节对齐
    sub rsp, 24
    xor r8, r8          # r8 存储累加和,初始为0
    mov r9, rdi         # r9 存储剩余循环次数,初始为N
    
loop:
    test r9, r9
    je end_loop
    dec r9
    
    # 调用scanf读取输入
    xor eax, eax
    mov rdi, offset scan_format
    mov rsi, offset var1
    call scanf
    
    # 读取输入的32位整数,符号扩展到64位
    movsxd rsi, dword ptr [var1]
    # 读取数组A的当前元素(r9为当前索引,int占4字节)
    mov rcx, qword ptr [A]
    movsxd rdx, dword ptr [rcx + r9*4]
    # 有符号数相乘
    imul rsi, rdx
    # 累加结果
    add r8, rsi
    
    jmp loop
    
end_loop:
    # 调用printf输出结果
    xor eax, eax
    mov rdi, offset print_format
    mov rsi, r8
    call printf
    
    add rsp, 24
    ret
    
.data
# 定义32位存储空间存输入
var1:
    .long 0

scan_format:
    .string "%d"
# 适配64位累加和输出,避免截断
print_format:
    .string "%lld\n"

补充说明:如果业务要求累加和只能是32位int,可以将累加寄存器换为32位寄存器,输出格式改回%d即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:45:06