x64-httpd/hello.s

187 lines
3.3 KiB
ArmAsm

global _start
; constants
SYS_READ equ 0
SYS_WRITE equ 1
SYS_POLL equ 7
SYS_SENDFILE equ 40
SYS_SOCKET equ 41
SYS_ACCEPT equ 43
SYS_BIND equ 49
SYS_LISTEN equ 50
SYS_EXIT equ 60
SYS_FCNTL equ 72
SYS_UNLINK equ 87
STDOUT equ 1
AF_UNIX equ 1
SOCK_STREAM equ 1
F_GETFL equ 3
F_SETFL equ 4
O_NONBLOCK equ 2048
POLLIN equ 1
POLLOUT equ 4
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
pollfds_capacity equ 100
SECTION .data
hello db "Hello world!", 0x0a
hello_len equ $ - hello
server_path db "server.sock", 0x00
server_path_len equ $ - hello
sockaddr_size equ 2 + 108 ; $ man 7 unix
SECTION .bss
sockaddr resb sockaddr_size
pollfds resb pollfd_size * pollfds_capacity
SECTION .text
_start:
mov rax, SYS_WRITE
mov rdi, STDOUT
mov rsi, hello
mov rdx, hello_len
syscall
call make_server
mov rbx, 0 ; pollfd array length
mov ebp, eax ; server fd
mov rax, rbx
mov edi, ebp
mov si, POLLIN
call pollfds__append
mov rbx, rax
mov rax, SYS_POLL
mov rdi, pollfds
mov rsi, rbx
mov rdx, 5000
syscall
exit:
mov rax, SYS_EXIT
mov rdi, 0
syscall
accept:
mov rdi, rax
mov rax, SYS_ACCEPT
mov rsi, 0
mov rdx, 0
syscall
ret
; rax - array length
; edi - fd
; si - events
; Returns new array length in rax
pollfds__append:
mov [pollfds + rax], edi
mov [pollfds + rax + 4], si
add rax, 1
ret
; Returns new array length in rax
; rax - array length
; edi - fd
pollfds__remove:
mov r10d, edi
mov rdi, 0
; Variables:
; rax - array length
; rdi - array index
; r10d - fd
; r11d - pollfds[rdi].fd
pollfds__remove__loop:
cmp rdi, rax
jge return ; fd was not found
mov r11d, [pollfds + rdi * pollfd_size]
add rdi, 1
cmp r11d, r10d
jne pollfds__remove__loop
sub rdi, 1
; Returns new array length in rax
; rax - array length
; rdi - array index to remove
pollfds__remove_index:
cmp rax, 1
jle pollfds__clear
mov r10d, [pollfds + (rax - 1) * pollfd_size]
mov [pollfds + rdi * pollfd_size], r10d
sub rax, 1
ret
; Returns new array length in rax
; rax - array length
pollfds__clear:
mov rax, 0
ret
; Returns (in rax) the server's file descriptor
make_server:
mov rax, SYS_UNLINK
mov rdi, server_path
syscall
mov rax, SYS_SOCKET
mov rdi, AF_UNIX
mov rsi, SOCK_STREAM
mov rdx, 0
syscall
push rax
call nonblocking
call make_sockaddr
pop r10
mov rax, SYS_BIND
mov rdi, r10
mov rsi, sockaddr
mov rdx, sockaddr_size
syscall
mov rax, SYS_LISTEN
mov rdi, r10
mov rsi, 100
syscall
mov rax, r10
ret
nonblocking:
mov r10, rax
mov rax, SYS_FCNTL
mov rdi, r10
mov rsi, F_GETFL
syscall
mov r11, rax
xor r11, O_NONBLOCK
mov rax, SYS_FCNTL
mov rdi, r10
mov rsi, F_SETFL
mov rdx, r11
syscall
ret
make_sockaddr:
mov word [sockaddr], AF_UNIX
mov rax, 0
make_sockaddr__copy_server_path:
cmp rax, server_path_len
jge return
mov r10, [server_path + rax]
mov [sockaddr + rax + 2], r10
add rax, 8
jmp make_sockaddr__copy_server_path
return:
ret