2016-09-14 4 views
0

В моей сборке программы я хочу, чтобы проверить, что стандартный ввод достиг EOFПочему чтение EOF делает scanf return 4294967295?

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 сделать зсапЕ признать EOF. Затем проверьте возвращаемое значение в rax, надеясь найти индикатор EOF (-1).

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

Я понимаю, что это значение -1 в дополнении двоичного кода. Хотя, я не понял, почему cmp rax, -1 не установил ZF (поскольку они равны).

Как определить EOF?

+1

64-бит -1 будет be '0xffffffffffffffff' – Michael

+0

Zapping EAX при входе и тестировании RAX по возвращении - намеренно? –

+0

@ Тому, да, я объяснил это в комментариях кода. –

ответ

2

Нет CMP r/m64, imm64 (или CMP RAX, imm64). Есть CMP RAX, imm32, который подписывает немедленный операнд до 64 бит, то есть -1 (0xffffffff) будет расширена знаком до 0xffffffffffffffff.

Если вы хотите сравнить RAX с 0xffffffff вы можете использовать что-то вроде:

mov ebx, -1 
cmp rax, rbx 

Или вы могли бы просто использовать EAX в сравнении, а не RAX:

cmp eax, -1 
+0

, но почему scanf вернул 0xffffffff (32 бит) в rax, а не 0xffffffffffffffff (64 бит) на машине amd64? Я читал человека на 64-битной машине Linux, и он не упоминает ограничение возвращаемого значения или его размер. У вас есть какие-то подсказки? –

+1

@BulatM. : потому что [scanf] (http://man7.org/linux/man-pages/man3/scanf.3.html) возвращает 32-разрядный 'int' не 64-разрядный' long' на 64-разрядный Linux. Поэтому вам нужно полагаться на данные в младших 32-битных файлах _RAX_. –

+2

@BulatM: Это будет зависеть от размера 'int', и как именно определяется' EOF'. Существует функция с именем 'feof', которая возвращает ненулевое значение, если для данного файла достигнуто EOF. Возможно, лучше использовать это, а не проверять EOF напрямую. – Michael