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

x64 AT&T汇编open系统调用返回EFAULT错误求助

问题分析与修复方案

核心问题原因

  1. 误用32位系统调用入口:x64架构下Linux必须使用syscall指令触发系统调用,int $0x80是32位兼容接口,会强制截断寄存器为32位,导致内核无法正确解析64位地址,直接触发EFAULT错误。
  2. 系统调用号与寄存器规则不匹配:32位open调用号是5,但x64下系统调用号、参数传递寄存器完全不同——x64要求:
    • rax 存储系统调用号
    • rdi 第一个参数(文件路径指针)
    • rsi 第二个参数(打开标志)
    • rdx 第三个参数(权限,仅O_CREAT生效)
    • 第四个参数用r10
  3. 文件名指针获取逻辑错误:你试图从16(%rbp)读取文件名,但该位置是命令行参数argv[1]的地址,而非你定义的filePath地址,完全偏离目标。
  4. 变量长度不兼容:fileHandle定义为4字节,但x64下文件句柄是8字节整数,长度不足会导致数据截断。

修复后的代码示例

.section .bss
    .lcomm fileBuffer, 50
    .lcomm fileHandle, 8  # 适配x64 8字节句柄

.section .data
filePath:
    .asciz "test.txt"
# x64标准系统调用定义
OPENAT:     .quad 257       # openat调用号(推荐替代直接open)
AT_FDCWD:   .quad -100      # 代表当前工作目录
OPEN_FLAGS: .quad 0102      # O_WRONLY | O_CREAT(八进制)
OPEN_PERMS: .quad 0444      # 文件权限(仅O_CREAT时生效)

.section .text
.globl _start

_start:
    # 准备openat系统调用参数
    movq AT_FDCWD, %rdi       # 第一个参数:当前目录句柄
    movq $filePath, %rsi      # 第二个参数:目标文件路径
    movq OPEN_FLAGS, %rdx     # 第三个参数:打开模式
    movq OPEN_PERMS, %r10     # 第四个参数:文件权限
    movq OPENAT, %rax         # 系统调用号存入rax
    syscall                   # 触发x64系统调用

    # 错误检查
    test %rax, %rax
    js badfile                # 若rax为负数(错误码),跳转到错误处理

# 正常流程代码(省略)
# ...

badfile:
    # 错误退出示例
    movq $60, %rax            # x64 exit系统调用号
    movq $1, %rdi             # 退出码1
    syscall

后续诊断方向

  • 用gdb调试:在syscall指令处打断点,查看rdi寄存器是否指向filePath的正确地址,确认参数传递无误。
  • 验证文件路径:确保test.txt存在于程序运行的当前工作目录,或改用绝对路径测试排除路径问题。
  • 编译运行检查:使用as -o test.o test.s && ld -o test test.o编译,运行前用pwd确认当前目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:55:45