.code64 #include .global read_buf .global write_buf .global passthru #define STDIN 0 #define STDOUT 1 #define STDERR 2 #define PF_INET 2 #define AF_INET PF_INET #define SOCK_STREAM 1 .section .rodata errstr: .ascii "error happened\n" .set errstr_len, .-errstr .bss .set buffer_size, 1024*1024 buffer: .skip buffer_size, 0 .text .func read_buf read_buf: test %rdx, %rdx jz read_exit mov %rdi, %r13 /* file */ mov %rsi, %r14 /* buffer */ mov %rdx, %r15 /* length */ read_seq: movq $__NR_read, %rax movq %r13, %rdi movq %r14, %rsi movq %r15, %rdx syscall cmp $-1, %rax jz error /* Yes we JUMP, not CALL */ test %rax, %rax jz read_empty add %rax, %r14 sub %rax, %r15 jnz read_seq /* we have more bytes! */ read_exit: ret read_empty: jmp error .endfunc .func write_buf write_buf: test %rdx, %rdx jz write_exit mov %rdi, %r13 /* file */ mov %rsi, %r14 /* buffer */ mov %rdx, %r15 /* length */ write_seq: movq $__NR_write, %rax movq %r13, %rdi movq %r14, %rsi movq %r15, %rdx syscall cmp $-1, %rax jz error /* Yes we JUMP, not CALL */ test %rax, %rax jz write_empty add %rax, %r14 sub %rax, %r15 jnz write_seq /* we have more bytes! */ write_exit: ret write_empty: jmp error .endfunc .func passthru passthru: push %rdi push %rsi passthru_step: movq $__NR_read, %rax movq 8(%rsp), %rdi movq $buffer, %rsi movq $buffer_size, %rdx syscall cmp $-1, %rax jz error /* Yes we JUMP, not CALL */ test %rax, %rax jz passthru_empty movq 0(%rsp), %rdi movq $buffer, %rsi movq %rax, %rdx call write_buf jmp passthru_step passthru_empty: passthru_exit: addq $16, %rsp ret .endfunc error: movq $__NR_write, %rax movq $STDERR, %rdi movq $errstr, %rsi movq $errstr_len, %rdx syscall movq $__NR_exit, %rax movq $2, %rdi syscall