echo-server/main.S
2016-02-21 01:00:03 +03:00

156 lines
2.4 KiB
ArmAsm

.code64
#include <asm/unistd.h>
#include <asm/socket.h>
#define STDIN 0
#define STDOUT 1
#define STDERR 2
#define PF_INET 2
#define AF_INET PF_INET
#define SOCK_STREAM 1
#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_fork, %rax
syscall /* fork! */
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 $0, %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 */