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