我在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
此指令无效:
%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来找到它,但是我不知道如何调用它。
答案 0 :(得分:1)
由于文件是按顺序读取的,因此在追加模式下调用sys_read后,光标将移至文件末尾,因此,如果尝试从该位置擦除,则希望读取任何内容。
要解决此问题,您必须将光标重新定位在文件的开头。
为此,您可以使用lseek系统调用。
mov rax, 8 ;system call Id for sys_lseek
mov rdi, [rsp] ;file descriptor
mov rsi, 0 ;offset value, so number of characters to move the cursor
mov rdx, 0 ;It indicates the initial position from which move the cursor, in this case the value 0 indicates that the initial position is the beginning of the file
syscall
调用此系统后,光标位置将位于文件的开头,您将可以从中读取文件。