【发布时间】:2020-01-10 03:54:27
【问题描述】:
我在 Nasm x86_64 中处理文件时遇到问题。 我已经正确打开了文件,我可以写入或读取它,但是如果我在写入文件后尝试从文件中读取一些东西,我什么也得不到。 所以我从文件中读取或写入。 奇怪的是,如果我第一次读写我没有任何问题并且一切正常,所以问题只是当我第一次写然后读时。 有人可以帮我解决这个问题并找出原因吗?
这是打开文件的代码:
mov rax, SYS_OPEN
mov rdi, filename
mov rsi, O_CREAT+O_RDWR+O_APPEND
mov rdx, 0744o
syscall
push rax
关闭文件的代码:
mov rax, SYS_CLOSE
mov rdi, r11
syscall
打印字符串的代码:
mov rdx, rax
mov rax, SYS_WRITE
mov rdi, STDOUT
mov rsi, temp
syscall
getLength的代码(参数是我要获取长度的字符串):
%macro getLength 1
mov r10, %1
mov r11, r10
%%begin:
cmp byte [r11], 10
je %%end
inc r11
jmp %%begin
%%end:
sub r11, r10
%endmacro
要写的代码:
getLength msg
mov rax, SYS_WRITE
mov rdi, [rsp]
mov rsi, msg
mov rdx, r11
syscall
阅读代码:
mov rax, SYS_READ
mov rdi, [rsp]
mov rsi, temp ;buffer to store the string read
mov rdx, 10
syscall
要读取的代码和要编写的代码都可以完美地单独工作,问题是当我在编写代码之后使用代码读取时。
所以这段代码有效。
%include "./standardlib.inc"
section .data
filename db "./file.txt", 0
msg db "hello", 10
section .bss
temp resb 10
section .text
global _start:
_start:
mov rax, SYS_OPEN
mov rdi, filename
mov rsi, O_CREAT+O_RDWR+O_APPEND
mov rdx, 0744o
syscall
push rax
mov rax, SYS_READ
mov rdi, [rsp]
mov rsi, temp
mov rdx, 10
syscall
mov rdx, rax
mov rax, SYS_WRITE
mov rdi, STDOUT
mov rsi, temp
syscall
getLength msg
mov rax, SYS_WRITE
mov rdi, [rsp]
mov rsi, msg
mov rdx, r11
syscall
mov rax, SYS_CLOSE
mov rdi, r11
syscall
exit
这个 coe 不起作用:
%include "./standardlib.inc"
section .data
filename db "./file.txt", 0
msg db "hello", 10
section .bss
temp resb 10
section .text
global _start:
_start:
mov rax, SYS_OPEN
mov rdi, filename
mov rsi, O_CREAT+O_RDWR+O_APPEND
mov rdx, 0744o
syscall
push rax
getLength msg
mov rax, SYS_WRITE
mov rdi, [rsp]
mov rsi, msg
mov rdx, r11
syscall
mov rax, SYS_READ
mov rdi, [rsp]
mov rsi, temp
mov rdx, 10
syscall
mov rdx, rax
mov rax, SYS_WRITE
mov rdi, STDOUT
mov rsi, temp
syscall
mov rax, SYS_CLOSE
mov rdi, r11
syscall
exit
所以我明白我必须使用 lseek 返回到文件的开头。 这是对 sys_lseek 的良好调用吗?
mov rax, 8 ;sys_lseek syscall ID
mov rdi, [rsp] ;file descriptor
mov rsi, 0 ;The offset
mov rdx, 0 ;I imagine the value of SEEK_SET
我猜是偏移值不对,应该用 ftell 找到,但是不知道怎么调用。
【问题讨论】:
-
您没有向我们展示
./standardlib.inc的内容,尤其是getlength的定义方式(我假设是一个宏)。不确定它是否返回 r11 中的值?那里似乎有些可疑。你能告诉我们getlength是如何出现在那个.inc文件中的吗? -
为什么要以追加模式打开文件?附加到文件后,您希望从文件中读取什么?如果您不知道附加模式的作用,请先阅读
open(2)的手册页。 -
@MichaelPetch 我没有放标准库的代码,因为我知道 getLength 工作正常,因为我在各种情况下使用它从来没有给我带来问题,如果它有问题也可能执行之前未写入文件的单次读取文件会引发问题。
-
@LeonardoDeFaveri 使用
SEEK_CUR和偏移量0 执行lseek。然后观察返回值。
标签: linux assembly x86-64 nasm system-calls