Jan*_*sen 5 linux assembly interrupt gnu-assembler system-calls
我有一个Linux x86-32 GAS汇编程序终止如下:
movl $1, %eax
movl $0, %ebx # argument for _exit
int $0x80
Run Code Online (Sandbox Code Playgroud)
当我像这样退出时,程序正常运行,但如果我尝试读取stdout输出,我什么也得不到(使用ie less或wc).
我尝试编译一个最小的C程序并比较strace输出.我发现的唯一区别是,GCC使得C程序(int main() { printf("donkey\n"); })隐含地退出exit_group(0)了strace输出.
我尝试修改我的ASM程序以退出call exit而不是原始系统调用.stdout现在可以正常读取.
测试用例
.data
douout: .string "monkey\n"
.text
.globl main
main:
pushl $douout
call printf
# Exit
movl $1, %eax
movl $0, %ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
编译并运行:
$ yasm -g dwarf2 -f elf -p gas t.asm && gcc -g -melf_i386 -o t t.o && ./t | wc -c
0
Run Code Online (Sandbox Code Playgroud)
预期:
7
Run Code Online (Sandbox Code Playgroud)
编辑:
我打过电话都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
Run Code Online (Sandbox Code Playgroud)
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
$
Run Code Online (Sandbox Code Playgroud)
谢谢大家,特别是没有.
当您通过管道将 stdout 传输到 wc 时,stdout 会完全缓冲。
_exit 立即终止进程,并且不运行 atexit() 和其他清理处理程序。运行时将注册此类处理程序,以便在退出时运行,刷新打开的 FILE*,例如 stdout。当这些处理程序在退出时未执行时,缓冲的数据将丢失。
如果您在 printf 调用之后调用fflush(stdout),或者您只是在控制台中运行该程序而不将输出通过管道传输到另一个程序,您应该会看到输出 - 在这种情况下,stdout 通常会进行行缓冲,因此每当您写入 \n 时,stdout 都会被刷新
| 归档时间: |
|
| 查看次数: |
970 次 |
| 最近记录: |