c# fgets在尝试fprint char* 时出现程序集x86_64错误

g52tjvyc  于 2023-03-11  发布在  C#
关注(0)|答案(1)|浏览(172)

我正在尝试使用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时会出错,我不知道可能的原因是什么。我也尝试过在读取的字符串中添加一个额外的终止空值,但是仍然存在同样的问题。

vybvopom

vybvopom1#

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

void foo(FILE *x)
{
    char str[1024];
    fgets(str, 1024, x);
    printf("%s", str);
    printf("%s", str);
    printf("%s", str);
    printf("%s", str);
}
  • 奥斯
.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
.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

https://godbolt.org/z/rjx4vh63n

相关问题