为什么读取 EOF 会使 scanf return 4294967295?

Why does reading EOF make scanf return 4294967295?

在我的汇编程序中,我想测试标准输入是否达到了 EOF

segment .data
    .fmt_read db "%80s", 0 ; 79 bytes of actual string + terminating 0

segment .text
    lea rdi, [.fmt_read]
    lea rsi, [buf_str]     ; buffer to fill in
    xor eax, eax           ; no floating-point parameters are passed
    call scanf
    cmp rax, -1            ; did we reach EOF(-1)
    je .done               ; yes? End the program

当我在 gdb 中调试它时,我按 Ctrl-D 让 scanf 识别 EOF。 然后测试rax中的return值,希望能找到一个EOF指标(-1).

(gdb) p $rax
 = 4294967295
(gdb) p/x $rax
 = 0xffffffff

我理解为二进制补码中的值-1。 虽然,我不明白为什么 cmp rax, -1 没有设置 ZF(因为它们是相等的)。

如何确定EOF?

没有CMP r/m64, imm64(或CMP RAX, imm64)。 CMP RAX, imm32 将立即操作数符号扩展为 64 位,即 -1 (0xffffffff) 将符号扩展为 0xffffffffffffffff.

如果你想比较 RAX0xffffffff 你可以使用类似的东西:

mov ebx, -1
cmp rax, rbx

或者您可以在比较中简单地使用 EAX 而不是 RAX:

cmp eax, -1