echo-server/main.S
2024-08-11 23:27:02 +03:00

163 lines
2.8 KiB
ArmAsm

.code64
#include <asm/unistd.h>
#define _LINUX_POSIX_TYPES_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 CLONE_PARENT 0x00008000
#define PORT 20335
.section .rodata
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
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
#define server_socket %rbx
#define connection_socket %r12
.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, server_socket
movq $__NR_setsockopt, %rax
movq server_socket, %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 server_socket, %rdi
movq $myaddr, %rsi
movq $myaddr_len, %rdx
syscall
test %rax, %rax
jnz error
movq $__NR_listen, %rax
movq server_socket, %rdi
movq $8, %rsi
syscall
test %rax, %rax
jnz error
loop:
movq $__NR_accept, %rax
movq server_socket, %rdi
movq $0, %rsi
movq $0, %rdx
movq $0, %r10
syscall
cmp $-1, %rax
jz error
movq %rax, connection_socket
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 connection_socket, %rdi
syscall
test %rax, %rax
jnz error
jmp loop
exit:
movq $__NR_close, %rax
movq server_socket, %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 connection_socket, %rdi
movq connection_socket, %rsi
call passthru
movq $__NR_close, %rax
movq connection_socket, %rdi
syscall
movq $__NR_exit, %rax
movq $0, %rdi
syscall
/* this line is unreachable */