echo server, multiple clients, lines <256 bytes
This commit is contained in:
parent
d54596514c
commit
29f54ba779
6 changed files with 304 additions and 112 deletions
104
client.s
Normal file
104
client.s
Normal file
|
@ -0,0 +1,104 @@
|
|||
; Errors (in rax):
|
||||
; 0 - EOF
|
||||
; -1024 - line too long
|
||||
; other negative - from read(2)
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - address of client within clients array
|
||||
; rdx - pollfds index
|
||||
client__pollin:
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
|
||||
mov r10, 0
|
||||
mov r10b, [rsi + 4 + 2] ; buffer_len
|
||||
|
||||
mov rdx, 0
|
||||
mov dl, 255
|
||||
sub dl, r10b ; rdx = 255 - buffer_len
|
||||
add rsi, 8
|
||||
add rsi, r10
|
||||
call readline
|
||||
|
||||
mov r10, rdi
|
||||
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
|
||||
cmp rax, 0
|
||||
jle return
|
||||
|
||||
add [rsi + 4 + 2], al ; buffer_len += rax
|
||||
|
||||
cmp r10, 0
|
||||
jg client__pollin__complete_line
|
||||
|
||||
add [rsi + 4 + 1], al ; line_len += rax
|
||||
ret
|
||||
|
||||
client__pollin__complete_line:
|
||||
add [rsi + 4 + 1], r10b ; line_len += r10
|
||||
mov word [pollfds + rdx * pollfd_size + 4], POLLOUT
|
||||
ret
|
||||
|
||||
; rdi - fd
|
||||
; rsi - address of client within clients array
|
||||
; rdx - pollfds index
|
||||
client__pollout:
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
|
||||
mov rax, SYS_WRITE
|
||||
mov rdx, 0
|
||||
mov dl, [rsi + 4 + 1]
|
||||
add rsi, 8
|
||||
syscall
|
||||
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
|
||||
cmp rax, 0
|
||||
jl return
|
||||
|
||||
mov r10, rsi
|
||||
add r10, 8
|
||||
mov r11, 0
|
||||
mov r11b, [rsi + 4 + 2]
|
||||
sub r11, rax
|
||||
add r11, r10
|
||||
|
||||
client__pollout__shunt:
|
||||
cmp r10, r11
|
||||
jge client__pollout__shunt__finished
|
||||
mov r8b, [r10 + rax]
|
||||
mov [r10], r8b
|
||||
add r10, 1
|
||||
jmp client__pollout__shunt
|
||||
|
||||
client__pollout__shunt__finished:
|
||||
sub [rsi + 4 + 2], al ; buffer_len -= rax
|
||||
sub [rsi + 4 + 1], al ; line_len -= rax
|
||||
cmp byte [rsi + 4 + 1], 0
|
||||
je client__pollout__wrote_line
|
||||
ret
|
||||
|
||||
client__pollout__wrote_line:
|
||||
mov word [pollfds + rdx * pollfd_size + 4], POLLIN
|
||||
ret
|
||||
|
||||
; rdi - fd
|
||||
client__shutdown_close:
|
||||
mov rax, SYS_SHUTDOWN
|
||||
push rdi
|
||||
mov rsi, SHUT_RDWR
|
||||
syscall
|
||||
|
||||
mov rax, SYS_CLOSE
|
||||
pop rdi
|
||||
syscall
|
||||
|
||||
ret
|
69
clients.s
Normal file
69
clients.s
Normal file
|
@ -0,0 +1,69 @@
|
|||
; edi - fd
|
||||
clients__append:
|
||||
; TODO check against client_capacity
|
||||
mov r10, [clients_len]
|
||||
imul r10, client_size
|
||||
add r10, clients
|
||||
mov [r10], edi
|
||||
|
||||
add qword [clients_len], 1
|
||||
|
||||
mov r11, 4
|
||||
|
||||
clients__append__write_zeros:
|
||||
cmp r11, 8
|
||||
jge return
|
||||
mov byte [r10 + r11], 0
|
||||
add r11, 1
|
||||
jmp clients__append__write_zeros
|
||||
|
||||
; edi - fd
|
||||
clients__search:
|
||||
mov r11, [clients_len]
|
||||
imul r11, client_size
|
||||
add r11, clients
|
||||
mov r10, clients
|
||||
|
||||
clients__search__loop:
|
||||
cmp r10, r11
|
||||
jge clients__search__fail
|
||||
mov r8d, [r10]
|
||||
cmp r8d, edi
|
||||
je clients__search__succ
|
||||
add r10, client_size
|
||||
jmp clients__search__loop
|
||||
|
||||
clients__search__fail:
|
||||
mov r10, -1
|
||||
|
||||
clients__search__succ:
|
||||
mov rax, r10
|
||||
ret
|
||||
|
||||
; rdi - address of client within clients array
|
||||
clients__remove:
|
||||
mov r10, [clients_len]
|
||||
cmp r10, 1
|
||||
jle clients__clear
|
||||
|
||||
add r10, -1
|
||||
mov [clients_len], r10
|
||||
|
||||
mov r10, 0
|
||||
mov r11, r10
|
||||
imul r11, client_size
|
||||
add r11, clients
|
||||
|
||||
clients__remove__loop:
|
||||
cmp r10, client_size
|
||||
jge return
|
||||
mov r8b, [r11 + r10]
|
||||
mov [rdi + r10], r8b
|
||||
add r10, 1
|
||||
jmp clients__remove__loop
|
||||
|
||||
; rdi - address of client within clients array
|
||||
clients__clear:
|
||||
mov r10, 0
|
||||
mov [clients_len], r10
|
||||
ret
|
|
@ -14,5 +14,7 @@ void main() {
|
|||
printf("sizeof(short) %d\n", sizeof(short));
|
||||
printf("POLLIN %d\n", POLLIN);
|
||||
printf("POLLOUT %d\n", POLLOUT);
|
||||
printf("POLLERR %d\n", POLLERR);
|
||||
printf("POLLNVAL %d\n", POLLNVAL);
|
||||
printf("SHUT_RDWR %d\n", SHUT_RDWR);
|
||||
}
|
||||
|
|
192
main.s
192
main.s
|
@ -22,11 +22,19 @@ F_SETFL equ 4
|
|||
O_NONBLOCK equ 2048
|
||||
POLLIN equ 1
|
||||
POLLOUT equ 4
|
||||
POLLERR equ 8
|
||||
POLLNVAL equ 32
|
||||
; TODO(?) POLLPRI: see poll(2), tcp(7)
|
||||
SHUT_RDWR equ 2
|
||||
|
||||
;STATE_READING equ 0
|
||||
;STATE_WRITING equ 1
|
||||
|
||||
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
|
||||
pollfds_capacity equ 100
|
||||
client_size equ 1 + 256 + 256 ; state, line buffer, uri
|
||||
|
||||
; fd, state, line_len, buffer_len, uri_len, buffer, uri
|
||||
client_size equ 4 + 4 + 255 + 255
|
||||
clients_capacity equ pollfds_capacity - 1
|
||||
|
||||
SECTION .data
|
||||
|
@ -47,11 +55,14 @@ SECTION .text
|
|||
|
||||
%include "server.s"
|
||||
%include "readline.s"
|
||||
%include "clients.s"
|
||||
%include "pollfds.s"
|
||||
%include "client.s"
|
||||
|
||||
_start:
|
||||
call make_server
|
||||
mov rbx, rax ; server fd
|
||||
mov rdi, rax
|
||||
mov rdi, rbx
|
||||
mov rsi, POLLIN
|
||||
call pollfds__append
|
||||
|
||||
|
@ -63,144 +74,113 @@ poll:
|
|||
syscall
|
||||
cmp rax, 0
|
||||
je poll
|
||||
jl exit ; TODO handle this gracefully
|
||||
mov rdi, rbx
|
||||
jl exit ; poll(2) returned error TODO
|
||||
|
||||
; rdi - server fd
|
||||
pollfds__scan:
|
||||
scan:
|
||||
mov r15, 0
|
||||
|
||||
pollfds__scan__loop:
|
||||
; Variables:
|
||||
; r15 - pollfds index
|
||||
; r14w - poll(2) revents
|
||||
; r13d - fd
|
||||
; r12 - client memory address
|
||||
scan__loop:
|
||||
cmp r15, [pollfds_len]
|
||||
jge poll
|
||||
mov r10w, [pollfds + r15 * pollfd_size + 6]
|
||||
cmp r10w, 0
|
||||
jne pollfds__scan__found
|
||||
mov r14w, [pollfds + r15 * pollfd_size + 6]
|
||||
cmp r14w, 0
|
||||
jne scan__found
|
||||
add r15, 1
|
||||
jmp pollfds__scan__loop
|
||||
jmp scan__loop
|
||||
|
||||
pollfds__scan__found:
|
||||
mov r14, 0
|
||||
mov r14d, [pollfds + r15 * pollfd_size]
|
||||
cmp r14d, edi
|
||||
je pollfds__scan__found__server
|
||||
scan__found:
|
||||
mov r13, 0
|
||||
mov r13d, [pollfds + r15 * pollfd_size]
|
||||
cmp r13d, ebx
|
||||
je scan__found__server
|
||||
|
||||
pollfds__scan__found__client:
|
||||
; TODO check r10w, incl for POLLNVAL & POLLERR
|
||||
push rdi
|
||||
scan__found__client:
|
||||
mov rdi, r13
|
||||
call clients__search
|
||||
mov r12, rax
|
||||
cmp r12, 0
|
||||
jl _client__not_stored
|
||||
|
||||
mov rdi, r14
|
||||
call clients__append
|
||||
mov r10w, r14w
|
||||
and r10w, POLLERR | POLLNVAL
|
||||
cmp r10w, 0
|
||||
jne _client__error
|
||||
|
||||
mov r12, [clients_len]
|
||||
add r12, -1
|
||||
imul r12, client_size
|
||||
add r12, clients
|
||||
add r12, 4
|
||||
mov r10w, r14w
|
||||
and r10w, POLLIN
|
||||
cmp r10w, 0
|
||||
jne _client__pollin
|
||||
|
||||
mov rdi, r14
|
||||
mov rsi, r12
|
||||
mov rdx, 256
|
||||
call readline
|
||||
cmp rax, 0 ; TODO
|
||||
jl exit
|
||||
;push rax ; TODO
|
||||
mov r10w, r14w
|
||||
and r10w, POLLOUT
|
||||
cmp r10w, 0
|
||||
jne _client__pollout
|
||||
|
||||
mov rdx, rax
|
||||
mov rax, SYS_WRITE
|
||||
mov rdi, r14
|
||||
mov rsi, r12
|
||||
syscall
|
||||
cmp rax, 0
|
||||
jl exit ; TODO handle this gracefully
|
||||
; TODO what did poll(2) detect in this case?
|
||||
add r15, 1
|
||||
jmp scan__loop
|
||||
|
||||
mov rax, SYS_SHUTDOWN
|
||||
mov rdi, 0
|
||||
mov edi, r14d
|
||||
mov rsi, SHUT_RDWR
|
||||
syscall
|
||||
|
||||
mov rax, SYS_CLOSE
|
||||
mov rdi, 0
|
||||
mov edi, r14d
|
||||
syscall
|
||||
_client__error:
|
||||
mov rdi, r12
|
||||
call clients__remove
|
||||
|
||||
_client__not_stored:
|
||||
mov rdi, r13
|
||||
call client__shutdown_close
|
||||
mov rdi, r15
|
||||
call pollfds__remove
|
||||
jmp scan__loop
|
||||
|
||||
pop rdi
|
||||
jmp pollfds__scan__loop
|
||||
_client__pollin:
|
||||
mov rdi, r13
|
||||
mov rsi, r12
|
||||
mov rdx, r15
|
||||
call client__pollin
|
||||
cmp rax, 0
|
||||
jle _client__error
|
||||
add r15, rax
|
||||
jmp scan__loop
|
||||
|
||||
pollfds__scan__found__server:
|
||||
; TODO check r10w, incl for POLLNVAL & POLLERR
|
||||
push rdi
|
||||
_client__pollout:
|
||||
mov rdi, r13
|
||||
mov rsi, r12
|
||||
mov rdx, r15
|
||||
call client__pollout
|
||||
add r15, 1
|
||||
jmp scan__loop
|
||||
|
||||
scan__found__server:
|
||||
cmp r14w, POLLIN
|
||||
jne exit
|
||||
|
||||
mov rax, SYS_ACCEPT
|
||||
mov rdi, r13
|
||||
mov rsi, 0
|
||||
mov rdx, 0
|
||||
syscall
|
||||
cmp rax, 0
|
||||
jl exit ; TODO handle this gracefully
|
||||
jl exit ; accept(2) returned error TODO
|
||||
|
||||
mov rdi, rax
|
||||
mov si, POLLIN | POLLOUT
|
||||
push rdi
|
||||
mov si, POLLIN
|
||||
call pollfds__append
|
||||
|
||||
pop rdi
|
||||
call clients__append
|
||||
|
||||
add r15, 1
|
||||
jmp pollfds__scan__loop
|
||||
|
||||
; edi - fd
|
||||
; si - events
|
||||
pollfds__append:
|
||||
; TODO check against pollfds_capacity
|
||||
mov r10, [pollfds_len]
|
||||
mov [pollfds + r10 * pollfd_size], edi
|
||||
mov [pollfds + r10 * pollfd_size + 4], si
|
||||
add r10, 1
|
||||
mov [pollfds_len], r10
|
||||
ret
|
||||
|
||||
; rdi - pollfds array index to remove
|
||||
pollfds__remove:
|
||||
mov r11, [pollfds_len]
|
||||
cmp rdi, r10
|
||||
jge return ; XXX index out of bounds, do some other error?
|
||||
cmp r11, 1
|
||||
jle pollfds__clear
|
||||
mov r10, [pollfds + (r11 - 1) * pollfd_size]
|
||||
mov [pollfds + rdi * pollfd_size], r10
|
||||
sub r11, 1
|
||||
mov [pollfds_len], r11
|
||||
ret
|
||||
|
||||
pollfds__clear:
|
||||
mov r10, 0
|
||||
mov [pollfds_len], r10
|
||||
ret
|
||||
|
||||
; esi - fd
|
||||
clients__append:
|
||||
; TODO check against client_capacity
|
||||
mov r10, [clients_len]
|
||||
imul r10, client_size
|
||||
add r10, clients
|
||||
mov [r10], esi
|
||||
add r10, 4
|
||||
mov r8b, 0
|
||||
mov r11, 0
|
||||
|
||||
clients__append__init:
|
||||
cmp r11, client_size
|
||||
jge return
|
||||
mov [r10 + r11], r8b
|
||||
add r11, 1
|
||||
jmp clients__append__init
|
||||
jmp scan__loop
|
||||
|
||||
return:
|
||||
ret
|
||||
|
||||
exit:
|
||||
mov rax, SYS_EXIT
|
||||
mov rdi, 0
|
||||
mov rdi, 255
|
||||
syscall
|
||||
|
|
30
pollfds.s
Normal file
30
pollfds.s
Normal file
|
@ -0,0 +1,30 @@
|
|||
; edi - fd
|
||||
; si - events
|
||||
pollfds__append:
|
||||
; TODO check against pollfds_capacity
|
||||
mov r10, [pollfds_len]
|
||||
mov [pollfds + r10 * pollfd_size], edi
|
||||
mov [pollfds + r10 * pollfd_size + 4], si
|
||||
mov r11w, 0
|
||||
mov [pollfds + r10 * pollfd_size + 6], r11w
|
||||
add r10, 1
|
||||
mov [pollfds_len], r10
|
||||
ret
|
||||
|
||||
; rdi - pollfds array index to remove
|
||||
pollfds__remove:
|
||||
mov r11, [pollfds_len]
|
||||
cmp rdi, r11
|
||||
jge return ; XXX index out of bounds, do some other error?
|
||||
cmp r11, 1
|
||||
jle pollfds__clear
|
||||
mov r10, [pollfds + (r11 - 1) * pollfd_size]
|
||||
mov [pollfds + rdi * pollfd_size], r10
|
||||
sub r11, 1
|
||||
mov [pollfds_len], r11
|
||||
ret
|
||||
|
||||
pollfds__clear:
|
||||
mov r10, 0
|
||||
mov [pollfds_len], r10
|
||||
ret
|
19
readline.s
19
readline.s
|
@ -1,34 +1,41 @@
|
|||
; Returns length in rax
|
||||
; Returns:
|
||||
; rax - read(2) length
|
||||
; rdi - if line is complete, line length;
|
||||
; if line was incomplete, 0;
|
||||
; if EOF or read(2) returned an error, undefined
|
||||
; Errors (in rax):
|
||||
; -1024 - line too long
|
||||
; other negative - error from read(2)
|
||||
; 0 - EOF from read(2)
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - buffer
|
||||
; rdx - max length
|
||||
readline:
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
mov rax, SYS_READ
|
||||
syscall
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
cmp rax, 0
|
||||
jl return
|
||||
mov r10, 0
|
||||
|
||||
readline__scan:
|
||||
cmp r10, rax
|
||||
cmp r10, rdx
|
||||
jge readline__overflow
|
||||
cmp r10, rax
|
||||
jge readline__incomplete_line
|
||||
mov r11b, [rsi + r10]
|
||||
add r10, 1
|
||||
cmp r11b, 0x0a ; '\n'
|
||||
jne readline__scan
|
||||
mov rdi, r10
|
||||
ret
|
||||
|
||||
readline__return:
|
||||
mov rax, r10
|
||||
readline__incomplete_line:
|
||||
mov rdi, 0
|
||||
ret
|
||||
|
||||
readline__overflow:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue