Assembly 使用文件“U name eq”后,我从open中得到一个默认错误;a、 txt";?

Assembly 使用文件“U name eq”后,我从open中得到一个默认错误;a、 txt";?,assembly,runtime-error,x86-64,nasm,system-calls,Assembly,Runtime Error,X86 64,Nasm,System Calls,我在运行名为time2.asm的汇编x86-64程序时收到一条错误消息 我正在使用Ubuntu x86-64 执行sys_open syscall后,rax寄存器将其值更改为-14-这意味着默认错误或“错误地址” 我的代码旨在打开一个名为“a.txt”的文件,检查是否发生错误,如果没有,则关闭该文件 我的代码: section .data file_name equ "a.txt" section .text global _start _start: ;---------------

我在运行名为
time2.asm的汇编x86-64程序时收到一条错误消息

我正在使用Ubuntu x86-64

执行sys_open syscall后,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
file\u name eq“a.txt”
file\u name
定义为仅作为汇编时间的数值常量1。本指令出现在哪一部分并不重要;它不会将任何字节组合到输出中
equ
纯粹是一个时间常数。类似于
%define
字符串替换,但它会当场将表达式计算为一个数字。(这对于涉及
$
的表达式很重要,例如
msglen eq$-msg

但您需要将字符串存储在内存中,并向系统调用传递指向以0结尾(隐式长度)的C字符串的指针。系统调用接口只接受指针,不接受值;否则它将无法处理长度超过8字节的文件名。(或32位系统中的4字节)

因此

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


脚注1:

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

文件名eq“a.txt”
完全等同于
文件名eq 0x7478742e61

文件名eq“a.txt”
仅将
文件名
定义为一个汇编时间数值常量。本指令出现在哪一部分并不重要;它不会将任何字节组合到输出中
equ
纯粹是一个时间常数。类似于
%define
字符串替换,但它会当场将表达式计算为一个数字。(这对于涉及
$
的表达式很重要,例如
msglen eq$-msg

但您需要将字符串存储在内存中,并向系统调用传递指向以0结尾(隐式长度)的C字符串的指针。系统调用接口只接受指针,不接受值;否则它将无法处理长度超过8字节的文件名。(或32位系统中的4字节)

因此

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


脚注1:

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


文件名eq“a.txt”
完全等同于
文件名eq 0x7478742e61
文件名eq“a.txt”
是错误的,我很惊讶它甚至可以进行汇编。请尝试使用
文件名db“a.txt”,改为0
。@Jester:这是一个数值常量:NASM允许在接受数值文本的任何上下文中使用多字符常量。e、 g.
mov eax,'1234'
在寄存器中提供4个ASCII字符。
文件名eq“a.txt”
是错误的,我很惊讶它甚至可以进行汇编。请尝试使用
文件名db“a.txt”,改为0
。@Jester:这是一个数值常量:NASM允许在接受数值文本的任何上下文中使用多字符常量。e、 g.
mov eax,'1234'
在寄存器中提供4个ASCII字符。
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