在汇编中使用 fgets 时出现分段错误错误?

Jan*_*ram 2 c x86 assembly glibc

fgets()在汇编中使用该函数,它应该可以工作,但是我的缓冲区有问题。有没有办法定义一个字符指针?我问是因为该函数需要一个字符指针作为第一个参数。

在这里你可以看到我的代码:

; nasm fgets.asm -f elf64 -o fgets.o
; gcc -no-pie fgets.o
; ./a.out

; Define fgets as an external function
extern fgets

SECTION .DATA
buffer: db "0000000000", 0

SECTION .TEXT
    global main

main:
    push rbp ; Push stack

    ; Set up parameters and call the C function

    mov rdi, buffer
    mov rsi,10
    mov rdx, 1
    mov rax,0
    call fgets

    pop rbp     ; Pop stack

    mov rax,0   ; Exit code 0
    ret         ; Return

Run Code Online (Sandbox Code Playgroud)

我想从标准输入中读取最多 10 个字符的内容。

JL2*_*210 5

AFILE *不是文件描述符。不是1像你那样传递,而是传递[stdin](这是有效的,因为它stdin是 glibc 中的一个全局指针,而stdinNASM 中的关键字是一个指向它的指针):

    mov rdx, [stdin]
Run Code Online (Sandbox Code Playgroud)

如果您使用 GAS,这将起作用:

    mov stdin, %rdx
Run Code Online (Sandbox Code Playgroud)

但是,您可能应该使用 RIP 相对寻址;这允许您的可执行文件被重新定位,并且是 PIE(位置无关可执行文件)所必需的,这是现在的默认设置。在 NASM 中,只需将其放在文件顶部:

default rel
Run Code Online (Sandbox Code Playgroud)

在 GAS 中,它有点复杂。您必须添加(%rip)到您使用的所有外部符号中,如下所示:

    mov stdin(%rip), %rdx
Run Code Online (Sandbox Code Playgroud)

这会将位于stdinFILE *您正在寻找的 8 字节指针)的内存加载到rdx.