我有一個Linux的x86-32 GAS的彙編程序終止這樣的:如何將_exit(0)(通過系統調用退出)阻止我接收任何標準輸出內容?
movl $1, %eax
movl $0, %ebx # argument for _exit
int $0x80
當我退出這個樣子,該程序的功能,如正常,但如果我嘗試讀取標準輸出的輸出,我什麼也沒得到(使用即少或wc)。
我試着編譯一個最小的C程序並比較strace輸出。我發現唯一的區別是,GCC在strace輸出中使C程序(int main() { printf("donkey\n"); }
)隱含退出exit_group(0)
。
我試着修改我的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
編輯:
我試過CAL凌tcflush
和fflush
,我仍然有問題。隨着fflush
我甚至得到一個段錯誤。
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 without newline in assembly
與往常一樣,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。
你會怎麼稱呼''fflush(stdout)''?根據''unistd.h'',fileno是1,但根據http://stackoverflow.com/questions/8502945/printf-without-newline-in-assembly,它是0. – 2012-03-18 00:58:39
stdout在這個上下文中是全局FILE *命名爲stdout(默認情況下連接到文件描述符1,標準輸出)。您不能使用文件描述符(0或1)作爲需要FILE *的函數的參數。你可以用NULL作爲參數調用fflush()來刷新所有打開的FILE *。 – nos 2012-03-18 01:10:59
但我不認爲程序集中有NULL?在C中,NULL == 0.它如何知道它的區別? – 2012-03-18 01:16:08