使用file_name equ“a.txt”后,我从open中得到一个EFAULT错误?

问题描述 投票:0回答:1

运行名为time2.asm的程序集x86-64程序时收到错误消息。

我使用的是Ubuntu x86-64。

执行sys_open系统调用后,rax寄存器将其值更改为-14 - 这意味着出现错误或“错误地址”。

我的代码用于打开一个名为“a.txt”的文件,检查是否发生错误,如果没有,请关闭该文件。

我的代码:

section .data

file_name equ "a.txt"

section .text

global _start
_start:

 ;--------------------------------------------------------------------
 ; first step-  I open a file called a.txt.

  mov rax, 2         ; sys_open
  mov rdi, file_name
  mov rsi, 0
  mov rdx, 0644q
  syscall        

  ;right after this syscall (sys_open), rax value changes to -14.


  cmp rax,0
  jl error        ;checks for error

  mov rdi,rax
  mov rax,3       ; sys_close
  syscall
  ;----------------------------------------------------------------------------

 error: mov rax,60
 mov rdi,0
 syscall ; exit program
assembly runtime-error x86-64 nasm system-calls
1个回答
2
投票

file_name equ "a.txt"file_name定义为仅汇编时数数字constant1。这个指令出现在哪个部分并不重要;它不会将任何字节汇集到输出中。 equ纯粹是一个装配时间不变的东西。与%define字符串替换类似,但它会将表达式计算为当场的数字。 (这对涉及$的表达很重要,如msglen equ $ - msg。)

但是你需要在内存中使用你的字符串,并向系统调用一个指向0终止(隐式长度)C字符串的指针。系统调用接口只接受指针,而不是值;否则它将无法处理超过8个字节的文件名。 (或32位系统中的4个字节)。

从而

default rel
section .rodata                  ; read-only data doesn't need to be in read-write .data

file_name: db "a.txt", 0         ; the 0 terminator is important, this is a C string.

section .text
...
    lea     rdi, [file_name]   ;or mov rsi, file_name for the inefficient way

在x86-64中将静态地址放入寄存器的标准方法是RIP相对LEA。 (default rel)。 mov edi, symbol适用于非PIE可执行文件,但基本上没有理由使用mov rdi, symbol(10字节mov r64, imm64)。


脚注1:

NASM允许在接受数字文字的任何上下文中使用多字符常量。例如mov rax, 'a.txt'完全等同于mov rax, 0x7478742e61,因此mov [mem], rax会将字符串放入内存(因为x86是little-endian),后跟3个字节的零。

file_name equ "a.txt"完全等同于file_name equ 0x7478742e61

© www.soinside.com 2019 - 2024. All rights reserved.