Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Nasm x86_64:为什么可以';我不能从同一个文件读写吗?_Linux_Assembly_X86 64_Nasm_System Calls - Fatal编程技术网

Linux Nasm x86_64:为什么可以';我不能从同一个文件读写吗?

Linux Nasm x86_64:为什么可以';我不能从同一个文件读写吗?,linux,assembly,x86-64,nasm,system-calls,Linux,Assembly,X86 64,Nasm,System Calls,我在Nasm x86_64中遇到文件处理问题。 我已经正确地打开了这个文件,我可以写入它或者从中读取,但是如果我在写入了一些东西之后尝试从文件中读取一些东西,我什么也得不到。 所以我从文件中读取或写入。 奇怪的是,如果我第一次读写,我没有任何问题,一切都很好,所以问题只出现在我先写然后读的时候。 有人能帮我解决这个问题并找出原因吗 以下是打开文件的代码: mov rax, SYS_OPEN mov rdi, filename mov rsi, O_

我在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     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的代码(参数是我要获取其长度的字符串):

要编写的代码:

    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来查找它,但我不知道如何调用它


由于文件是按顺序读取的,因此在附加模式下调用sys\u 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

调用此系统调用后,光标位置将位于文件的开头,您将能够从中读取。

您不会向我们显示
/standardlib.inc
的内容,尤其是
getlength
的定义(我假设为宏)。不确定它是否返回r11中的值?那里似乎有些可疑。你能告诉我们
getlength
是如何显示在该.inc文件中的吗?你为什么要以附加模式打开该文件?附加到文件后,您希望从该文件中读取什么?如果您不知道追加模式的作用,请先阅读
open(2)
的手册页。阅读的文档,我们看到:写入发生在当前文件偏移量处,文件偏移量按实际写入的字节数递增。由于要写入文件的末尾(由于O_追加),因此写入后的文件位置也将是文件的结尾。没有更多的东西要读了,因为它在文件的末尾。也许你需要的是?@MichaelPetch我没有使用standardlib的代码,因为我知道getLength可以很好地工作,因为我在不同的场合使用过它,它从来没有给我带来问题,如果它也有问题,那么在没有写入文件的情况下对文件执行一次读取可能会引起问题。@Leonardefaveri使用
SEEK\CUR
执行
lseek
,偏移量为0。然后观察返回值。还要注意,如果知道要从哪个位置读取,只需使用
pread()
(位置读取)系统调用,而不是
lseek
+
read
pread
不会移动fd的文件位置。但是,如果您想为可能的多个
读取
s倒带文件位置,则可以使用
lseek