我正在 x86_64 Linux 上的 NASM 中构建和运行代码。
程序从我的程序中调用 GNU libc printf
函数。
该程序只需在标准输出上打印一个句子即可。
; comment
section .data
fmt: db "Hello %s %c", 0
name: db "Jane Doe", 0
section .text
global _start
extern printf
func:
lea rdi, [fmt]
lea rsi, [name]
mov rcx, 0x0A
xor rax, rax
call printf
ret
_start:
call func
; exit
mov rax, 1
mov rbx, 0
int 80h
ret
这是我编译它的方式:
nasm -f elf64 Program.s -o Program.o -Werror
ld -m elf_x86_64 Program.o -o Program -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2
当我运行程序时,它输出到终端Hello Jane Doe
。好的,那是我所期望的。
但是当我将输出重定向如下时:
./Program > output.txt
文件output.txt
为空。
-rw-rw-r-- 1 me me 0 output.txt
有什么主意吗?看来libc printf
在这种情况下正在打印到stdout
以外的另一个文件描述符中,但也许我错了。
用户已在评论中找到了解决方案。
切换
; exit
mov rax, 1
mov rbx, 0
int 80h
{p> by call exit
做到了。
答案 0 :(得分:2)
如果要使用C库函数,则不应使用_start
,而应使用旧的main
。如果您从libc盗用_start
,它将无法执行多项设置和清除操作,例如刷新打开的C文件。
在这种情况下,仅当写入文件时才可见,因为写入tty stdout默认情况下是行缓冲的,因此会立即刷新。重定向到文件时,数据只是复制到一个临时缓冲区中,当数据已满或终止时将被刷新-但是在您的情况下从未调用过C运行时清理函数,因此,数据实际上从未被调用过传递给操作系统。
另一种可能性是使用exit
libc函数退出,该函数应该处理清除操作,但是我不确定libc的内容是否即使没有机会被要求工作也可以正常工作首先初始化。