У меня есть программа сборки Linux x86-32 GAS, завершающаяся следующим образом:
movl $1, %eax
movl $0, %ebx # argument for _exit
int $0x80
Когда я выхожу так, программа работает как обычно, но если я пытаюсь прочитать вывод stdout, я получаюничего (используя т.е. less или wc).
Я попытался скомпилировать минимальную C-программу и сравнить результаты работы strace.Единственное различие, которое я обнаружил, заключалось в том, что GCC заставил программу на C (int main() { printf("donkey\n"); }
) неявно завершить работу с exit_group(0)
в выводе strace.
Я попытался изменить свою программу ASM для выхода с call exit
вместосырой системный вызов.Теперь стандартный вывод читался как обычно.
Контрольный пример
.data
douout: .string "monkey\n"
.text
.globl main
main:
pushl $douout
call printf
# Exit
movl $1, %eax
movl $0, %ebx
int $0x80
Скомпилируйте и запустите:
$ yasm -g dwarf2 -f elf -p gas t.asm && gcc -g -melf_i386 -o t t.o && ./t | wc -c
0
Ожидается:
7
РЕДАКТИРОВАТЬ:
Я пытался позвонить и tcflush
и fflush
, и у меня все еще есть проблема.С fflush
я даже получаю segfault.
0xb7e9e7c9 in _IO_fflush (fp=0x804a018) at iofflush.c:42
42 iofflush.c: No such file or directory.
in iofflush.c
(gdb) bt
#0 0xb7e9e7c9 in _IO_fflush (fp=0x804a018) at iofflush.c:42
#1 0x08048434 in main () at t.asm:12
(gdb) frame 1
#1 0x08048434 in main () at t.asm:12
12 call fflush
(gdb) list
7
8 pushl $douout
9 call printf
10 # Exit
11 movl $0, %eax
12 call fflush
13 movl $1, %eax
14 movl $0, %ebx
15 int $0x80
EDIT2:
Хорошо, теперь все работает.Я использовал неправильное соглашение о вызовах, которое скопировал отсюда: Printf без перевода строки в сборке
Аргумент для fflush
должен быть в стеке, как обычно.
$ cat t.asm
.data
douout: .string "monkey\n"
.text
.globl main
main:
pushl $douout
call printf
# Exit
pushl $0
call fflush
movl $1, %eax
movl $0, %ebx
int $0x80
$ yasm -g dwarf2 -f elf -p gas t.asm && gcc -g -melf_i386 -o t t.o && ./t | wc -c
7
$
Спасибо всем, особенно nos.