2015-11-25 14 views
9

Tôi đã viết một chương trình đơn giản NASM:Tại sao không thể stdout từ gọi c printf thư viện trong asm được đường ống đến các chương trình khác?

printtest.asm

section .data 
str_out db "val = %d",10,0 

section .text 

global main 

extern printf 

main: 

    PUSH 5 
    PUSH DWORD str_out 
    CALL printf 
    ADD ESP, 8 
    MOV EAX, 1 
    INT 80h 

tôi đang liên kết và tạo ra một thực thi với các lệnh sau:

nasm -f elf -l printtest.lst printtest.asm 
gcc -o printtest printtest.o 

Khi liên kết và thực hiện, điều này in "val = 5" để giao diện điều khiển không có vấn đề. Theo như tôi biết, hãy gọi printf theo mặc định viết trên stdout. Vì vậy, tại sao khi tôi cố gắng và ống này để chương trình khác không chương trình khác dường như không nhận được đầu vào?

ví dụ

./printtest | cat 

Dường như không phải làm gì

Tôi chắc chắn tôi về cơ bản sự hiểu lầm gì đó ở đây.

Trả lời

11

Chức năng stdio C có thể được đệm theo mặc định, do đó, viết thành stdout với printf không phải lúc nào cũng thực hiện bất kỳ thứ gì - đôi khi nó chỉ ghi vào bộ đệm, đang chờ xóa tiếp theo. Thông thường, liệu một luồng stdio nhất định có được đệm hay không phụ thuộc vào việc nó được kết nối với một thiết bị đầu cuối hay một đường ống hay một tệp hay một thứ gì đó khác.

Khi bạn gọi cuộc gọi hệ thống thoát (như bạn làm), mọi dữ liệu vẫn còn trong bộ đệm sẽ bị mất. Thay vào đó, nếu bạn gọi hàm C thư viện exit, nó sẽ xóa tất cả bộ đệm trước khi thực sự thoát.

+0

Bạn là một vị thần trong số những người đàn ông. Cảm ơn bạn! – Jake

+0

'return 0;' từ main() có thực hiện được điều tương tự không? Chỉ cần tò mò (và tôi không ở một vị trí mà tôi có thể điều này ngay bây giờ). – keithmo

+0

Nên làm. Lưu ý rằng viết 'main' của riêng bạn trong asm và sau đó gọi thư viện C không phải là bảo đảm an toàn - một số triển khai C dựa vào mã đặc biệt được thêm vào' main' bởi trình biên dịch để khởi tạo thư viện chuẩn đúng cách. Tuy nhiên, Linux nên được sử dụng tốt. –

Các vấn đề liên quan