.code64 #include #include #define STDIN 0 #define STDOUT 1 #define STDERR 2 #define PF_INET 2 #define AF_INET PF_INET #define SOCK_STREAM 1 #define CLONE_PARENT 0x00008000 #define PORT 20335 .data greeting: .ascii "Welcome to the minimalistic echo server!\n" .ascii "It is written in pure assembly, and it don't use the standard library, only raw system calls.\n" .ascii "\n" .ascii "To exit, press Ctrl+C, as usual\n" .ascii "\n" .set greeting_len, .-greeting message: .ascii "Client connected\n" .set message_len, .-message errstr: .ascii "Error happened\n" .set errstr_len, .-errstr s: .quad 0 s2: .quad 0 true_val: .quad 1 .set true_val_len, .-true_val myaddr: .hword AF_INET port: .byte (PORT >> 8) & 0xFF, (PORT & 0xFF) addr: .byte 0, 0, 0, 0 .set myaddr_len, 16 .extern passthru .extern write_buf .text .global _start _start: movq $STDOUT, %rdi movq $greeting, %rsi movq $greeting_len, %rdx call write_buf movq $__NR_socket, %rax movq $PF_INET, %rdi movq $SOCK_STREAM, %rsi movq $0, %rdx syscall cmp $-1, %rax jz error movq %rax, s movq $__NR_setsockopt, %rax movq s, %rdi movq $SOL_SOCKET, %rsi movq $SO_REUSEADDR, %rdx movq $true_val, %r10 movq $true_val_len, %r8 syscall test %rax, %rax jnz error movq $__NR_bind, %rax movq s, %rdi movq $myaddr, %rsi movq $myaddr_len, %rdx syscall test %rax, %rax jnz error movq $__NR_listen, %rax movq s, %rdi movq $8, %rsi syscall test %rax, %rax jnz error loop: movq $__NR_accept, %rax movq s, %rdi movq $0, %rsi movq $0, %rdx movq $0, %r10 syscall cmp $-1, %rax jz error movq %rax, s2 movq $STDOUT, %rdi movq $message, %rsi movq $message_len, %rdx call write_buf movq $__NR_clone, %rax movq $CLONE_PARENT, %rdi movq $0, %rsi movq $0, %rdx movq $0, %r10 movq $0, %r8 syscall /* fork! (through clone()) */ cmp $-1, %rax jz error test %rax, %rax jz child /* we're in the parent if we reach this line */ movq $__NR_close, %rax movq s2, %rdi syscall test %rax, %rax jnz error jmp loop exit: movq $__NR_close, %rax movq s, %rdi syscall test %rax, %rax jnz error movq $__NR_exit, %rax movq $0, %rdi syscall /* this line is unreachable */ error: movq $__NR_write, %rax movq $STDOUT, %rdi movq $errstr, %rsi movq $errstr_len, %rdx syscall movq $__NR_exit, %rax movq $1, %rdi syscall /* this line is unreachable */ child: /* we're in the child if we reach this line */ movq s2, %rdi movq s2, %rsi call passthru movq $__NR_close, %rax movq s2, %rdi syscall movq $__NR_exit, %rax movq $0, %rdi syscall /* this line is unreachable */