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("sizeof(short) %d\n", sizeof(short));
|
||||||
printf("POLLIN %d\n", POLLIN);
|
printf("POLLIN %d\n", POLLIN);
|
||||||
printf("POLLOUT %d\n", POLLOUT);
|
printf("POLLOUT %d\n", POLLOUT);
|
||||||
|
printf("POLLERR %d\n", POLLERR);
|
||||||
|
printf("POLLNVAL %d\n", POLLNVAL);
|
||||||
printf("SHUT_RDWR %d\n", SHUT_RDWR);
|
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
|
O_NONBLOCK equ 2048
|
||||||
POLLIN equ 1
|
POLLIN equ 1
|
||||||
POLLOUT equ 4
|
POLLOUT equ 4
|
||||||
|
POLLERR equ 8
|
||||||
|
POLLNVAL equ 32
|
||||||
|
; TODO(?) POLLPRI: see poll(2), tcp(7)
|
||||||
SHUT_RDWR equ 2
|
SHUT_RDWR equ 2
|
||||||
|
|
||||||
|
;STATE_READING equ 0
|
||||||
|
;STATE_WRITING equ 1
|
||||||
|
|
||||||
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
|
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
|
||||||
pollfds_capacity equ 100
|
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
|
clients_capacity equ pollfds_capacity - 1
|
||||||
|
|
||||||
SECTION .data
|
SECTION .data
|
||||||
|
@ -47,11 +55,14 @@ SECTION .text
|
||||||
|
|
||||||
%include "server.s"
|
%include "server.s"
|
||||||
%include "readline.s"
|
%include "readline.s"
|
||||||
|
%include "clients.s"
|
||||||
|
%include "pollfds.s"
|
||||||
|
%include "client.s"
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
call make_server
|
call make_server
|
||||||
mov rbx, rax ; server fd
|
mov rbx, rax ; server fd
|
||||||
mov rdi, rax
|
mov rdi, rbx
|
||||||
mov rsi, POLLIN
|
mov rsi, POLLIN
|
||||||
call pollfds__append
|
call pollfds__append
|
||||||
|
|
||||||
|
@ -63,144 +74,113 @@ poll:
|
||||||
syscall
|
syscall
|
||||||
cmp rax, 0
|
cmp rax, 0
|
||||||
je poll
|
je poll
|
||||||
jl exit ; TODO handle this gracefully
|
jl exit ; poll(2) returned error TODO
|
||||||
mov rdi, rbx
|
|
||||||
|
|
||||||
; rdi - server fd
|
scan:
|
||||||
pollfds__scan:
|
|
||||||
mov r15, 0
|
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]
|
cmp r15, [pollfds_len]
|
||||||
jge poll
|
jge poll
|
||||||
mov r10w, [pollfds + r15 * pollfd_size + 6]
|
mov r14w, [pollfds + r15 * pollfd_size + 6]
|
||||||
cmp r10w, 0
|
cmp r14w, 0
|
||||||
jne pollfds__scan__found
|
jne scan__found
|
||||||
add r15, 1
|
add r15, 1
|
||||||
jmp pollfds__scan__loop
|
jmp scan__loop
|
||||||
|
|
||||||
pollfds__scan__found:
|
scan__found:
|
||||||
mov r14, 0
|
mov r13, 0
|
||||||
mov r14d, [pollfds + r15 * pollfd_size]
|
mov r13d, [pollfds + r15 * pollfd_size]
|
||||||
cmp r14d, edi
|
cmp r13d, ebx
|
||||||
je pollfds__scan__found__server
|
je scan__found__server
|
||||||
|
|
||||||
pollfds__scan__found__client:
|
scan__found__client:
|
||||||
; TODO check r10w, incl for POLLNVAL & POLLERR
|
mov rdi, r13
|
||||||
push rdi
|
call clients__search
|
||||||
|
mov r12, rax
|
||||||
|
cmp r12, 0
|
||||||
|
jl _client__not_stored
|
||||||
|
|
||||||
mov rdi, r14
|
mov r10w, r14w
|
||||||
call clients__append
|
and r10w, POLLERR | POLLNVAL
|
||||||
|
cmp r10w, 0
|
||||||
|
jne _client__error
|
||||||
|
|
||||||
mov r12, [clients_len]
|
mov r10w, r14w
|
||||||
add r12, -1
|
and r10w, POLLIN
|
||||||
imul r12, client_size
|
cmp r10w, 0
|
||||||
add r12, clients
|
jne _client__pollin
|
||||||
add r12, 4
|
|
||||||
|
|
||||||
mov rdi, r14
|
mov r10w, r14w
|
||||||
mov rsi, r12
|
and r10w, POLLOUT
|
||||||
mov rdx, 256
|
cmp r10w, 0
|
||||||
call readline
|
jne _client__pollout
|
||||||
cmp rax, 0 ; TODO
|
|
||||||
jl exit
|
|
||||||
;push rax ; TODO
|
|
||||||
|
|
||||||
mov rdx, rax
|
; TODO what did poll(2) detect in this case?
|
||||||
mov rax, SYS_WRITE
|
add r15, 1
|
||||||
mov rdi, r14
|
jmp scan__loop
|
||||||
mov rsi, r12
|
|
||||||
syscall
|
|
||||||
cmp rax, 0
|
|
||||||
jl exit ; TODO handle this gracefully
|
|
||||||
|
|
||||||
mov rax, SYS_SHUTDOWN
|
_client__error:
|
||||||
mov rdi, 0
|
mov rdi, r12
|
||||||
mov edi, r14d
|
call clients__remove
|
||||||
mov rsi, SHUT_RDWR
|
|
||||||
syscall
|
|
||||||
|
|
||||||
mov rax, SYS_CLOSE
|
|
||||||
mov rdi, 0
|
|
||||||
mov edi, r14d
|
|
||||||
syscall
|
|
||||||
|
|
||||||
|
_client__not_stored:
|
||||||
|
mov rdi, r13
|
||||||
|
call client__shutdown_close
|
||||||
mov rdi, r15
|
mov rdi, r15
|
||||||
call pollfds__remove
|
call pollfds__remove
|
||||||
|
jmp scan__loop
|
||||||
|
|
||||||
pop rdi
|
_client__pollin:
|
||||||
jmp pollfds__scan__loop
|
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:
|
_client__pollout:
|
||||||
; TODO check r10w, incl for POLLNVAL & POLLERR
|
mov rdi, r13
|
||||||
push rdi
|
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 rax, SYS_ACCEPT
|
||||||
|
mov rdi, r13
|
||||||
mov rsi, 0
|
mov rsi, 0
|
||||||
mov rdx, 0
|
mov rdx, 0
|
||||||
syscall
|
syscall
|
||||||
cmp rax, 0
|
cmp rax, 0
|
||||||
jl exit ; TODO handle this gracefully
|
jl exit ; accept(2) returned error TODO
|
||||||
|
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
mov si, POLLIN | POLLOUT
|
push rdi
|
||||||
|
mov si, POLLIN
|
||||||
call pollfds__append
|
call pollfds__append
|
||||||
|
|
||||||
pop rdi
|
pop rdi
|
||||||
|
call clients__append
|
||||||
|
|
||||||
add r15, 1
|
add r15, 1
|
||||||
jmp pollfds__scan__loop
|
jmp 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
|
|
||||||
|
|
||||||
return:
|
return:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mov rax, SYS_EXIT
|
mov rax, SYS_EXIT
|
||||||
mov rdi, 0
|
mov rdi, 255
|
||||||
syscall
|
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):
|
; Errors (in rax):
|
||||||
; -1024 - line too long
|
; -1024 - line too long
|
||||||
; other negative - error from read(2)
|
; other negative - error from read(2)
|
||||||
|
; 0 - EOF from read(2)
|
||||||
; Arguments:
|
; Arguments:
|
||||||
; rdi - fd
|
; rdi - fd
|
||||||
; rsi - buffer
|
; rsi - buffer
|
||||||
; rdx - max length
|
; rdx - max length
|
||||||
readline:
|
readline:
|
||||||
push rdi
|
|
||||||
push rsi
|
push rsi
|
||||||
push rdx
|
push rdx
|
||||||
mov rax, SYS_READ
|
mov rax, SYS_READ
|
||||||
syscall
|
syscall
|
||||||
pop rdx
|
pop rdx
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rdi
|
|
||||||
cmp rax, 0
|
cmp rax, 0
|
||||||
jl return
|
jl return
|
||||||
mov r10, 0
|
mov r10, 0
|
||||||
|
|
||||||
readline__scan:
|
readline__scan:
|
||||||
cmp r10, rax
|
cmp r10, rdx
|
||||||
jge readline__overflow
|
jge readline__overflow
|
||||||
|
cmp r10, rax
|
||||||
|
jge readline__incomplete_line
|
||||||
mov r11b, [rsi + r10]
|
mov r11b, [rsi + r10]
|
||||||
add r10, 1
|
add r10, 1
|
||||||
cmp r11b, 0x0a ; '\n'
|
cmp r11b, 0x0a ; '\n'
|
||||||
jne readline__scan
|
jne readline__scan
|
||||||
|
mov rdi, r10
|
||||||
|
ret
|
||||||
|
|
||||||
readline__return:
|
readline__incomplete_line:
|
||||||
mov rax, r10
|
mov rdi, 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
readline__overflow:
|
readline__overflow:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue