fgets in assembly x86_64 errors when trying to fprint char*

问题描述 投票:0回答:1

我正在尝试使用 fgets 逐行读取文件。该子例程是从一个 c 测试文件中调用的,其中第一个参数是我试图从中读取的 FILE*。 这是我到目前为止编写的代码:

.text
    char: .asciz "%c"
    string: .asciz "%s"

diff: #void diff(FILE* pFile)
    pushq %rbp
    movq %rsp, %rbp

    subq $1024, %rsp

    movq %rdi, %rdx
    leaq -1024(%rbp), %rdi
    movq $1024, %rsi
    call fgets

    movq %rax, %rsi
    leaq string(%rip), %rdi
    movq $0, %rax
    call printf # printing rax is fine

    movq -1024(%rbp), %rsi
    leaq char(%rip), %rdi
    movq $0, %rax
    call printf # printing with %c is fine

    movq -1024(%rbp), %rsi
    leaq string(%rip), %rdi
    movq $0, %rax
    call printf # printing with %s will error

    movq %rbp, %rsp
    popq %rbp

代码在最后一个 printf 期间会出错,我无法弄清楚可能的原因是什么。我还尝试向读取的字符串添加一个额外的终止空值,但是同样的问题仍然存在。

c assembly x86-64 att
1个回答
0
投票

将您的代码与生成的编译器进行比较:

-Os

.LC0:
        .string "%s"
foo:
        subq    $1032, %rsp
        movq    %rdi, %rdx
        movl    $1024, %esi
        movq    %rsp, %rdi
        call    fgets
        movq    %rsp, %rsi
        movl    $.LC0, %edi
        xorl    %eax, %eax
        call    printf
        movq    %rsp, %rsi
        movl    $.LC0, %edi
        xorl    %eax, %eax
        call    printf
        movq    %rsp, %rsi
        movl    $.LC0, %edi
        xorl    %eax, %eax
        call    printf
        movq    %rsp, %rsi
        movl    $.LC0, %edi
        xorl    %eax, %eax
        call    printf
        addq    $1032, %rsp
        ret

-O0

.LC0:
        .string "%s"
foo:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $1040, %rsp
        movq    %rdi, -1032(%rbp)
        movq    -1032(%rbp), %rdx
        leaq    -1024(%rbp), %rax
        movl    $1024, %esi
        movq    %rax, %rdi
        call    fgets
        leaq    -1024(%rbp), %rax
        movq    %rax, %rsi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        leaq    -1024(%rbp), %rax
        movq    %rax, %rsi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        leaq    -1024(%rbp), %rax
        movq    %rax, %rsi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        leaq    -1024(%rbp), %rax
        movq    %rax, %rsi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        nop
        leave
        ret
© www.soinside.com 2019 - 2024. All rights reserved.