Compare commits

...

10 commits

Author SHA1 Message Date
4432178af9 Bugfix for newline exit
When stdin is close instead of pressing enter
2018-09-10 02:40:38 +02:00
5929efa54b Reducing nop in allignement 2018-09-10 02:30:44 +02:00
8b63d50095 Argument parsing code enhancement
Using call & ret (but that's maybe not necessary...)
Reducing instruction size
2018-09-10 02:20:23 +02:00
36abef3e4e More main_loop and _start code enhancement 2018-09-10 02:19:32 +02:00
a675c1fd79 main_loop and _start proc enhancement
main_loop alignement and size reduction under 32 bytes
Size reduction of _start code
2018-09-09 19:01:01 +02:00
8b427138e0 Allign proc_print_time loops 2018-09-09 17:30:53 +02:00
511afacfe9 Add write error checks 2018-09-09 16:56:05 +02:00
0da7000028 Bugfix in sleep time calculation 2018-09-09 16:54:51 +02:00
9009013637 Reducing proc_print_time size
Using smaller operations
2018-09-09 16:53:29 +02:00
a6f66401cb Moved TIMESPEC data out of BSS 2018-09-09 16:44:09 +02:00

View file

@ -27,6 +27,8 @@
; press enter to exit
; send SIGINT (with kill -2 ir ctrl + c) for a new lap
[bits 64]
%use smartalign
ALIGNMODE k8
%define O_NONBLOCK 0x800
@ -38,8 +40,8 @@ ENDSTRUC
%macro TIMESPEC 1
%1: ISTRUC TIMESPEC_STRUC
at TIMESPEC_STRUC.tv_sec, resq 1
at TIMESPEC_STRUC.tv_nsec, resq 1
at TIMESPEC_STRUC.tv_sec, dq 0
at TIMESPEC_STRUC.tv_nsec, dq 0
IEND
%define %1.tv_sec %1+TIMESPEC_STRUC.tv_sec
%define %1.tv_nsec %1+TIMESPEC_STRUC.tv_nsec
@ -66,20 +68,15 @@ ENDSTRUC
%define sigaction.sa_mask sigaction+SIGACTION_STRUC.sa_mask
%endmacro
section .bss
section .data
align 8
TIMESPEC ts_start
TIMESPEC ts_cur
TIMESPEC ts_sleep
buf: resb 1
section .data
time_res: dq 2 ; 2 digits bellow seconds can grow to 8
fcntl_flag: dq 0
SIGACTION sigaction
align 8
hours: times 8 db '0' ; 8 digits is the max for hours
timestr: db ":00:00."
times 8 db '0' ; 8 digits for nanoseconds
@ -89,6 +86,11 @@ section .data
timestrlen: equ timestrend - timestr
%define HOURSLEN 8
buf: db 0
fcntl_flag: dq 0
SIGACTION sigaction
lapsmsg: db "Lap : "
lapsmsglen: equ $ - lapsmsg
@ -134,8 +136,10 @@ global _start
_start:
; parse arguments and set time_res value
jmp arg_parse
arg_ok:
call arg_parse
mov rbx, ts_start
%define RBXPTR(x) rbx + x - ts_start
; set stdin reads non blocking
xor rdx, rdx
@ -143,26 +147,28 @@ xor rdi, rdi
mov rax, 72 ; fcntl
mov rsi, 3 ; F_GETFL
syscall
mov [fcntl_flag], rax
mov [RBXPTR(fcntl_flag)], rax
mov rdx, rax
or rdx, O_NONBLOCK
or dx, O_NONBLOCK
mov rax, 72 ; fcntl
mov rsi, 4 ; F_SETFL
syscall
cmp rax, 0
jne fault
test al, al
js fault
; preparing SIGINT catch
mov rax, proc_lap_handler
mov qword [sigaction.sa_handler], rax
mov eax, 0x14000000 ; SA_RESTART | SA_RESTORER
mov dword [sigaction.sa_flags], eax
mov rax, sig_restorer
mov qword [sigaction.sa_restorer], rax
mov qword [RBXPTR(sigaction.sa_handler)], rax
mov ecx, 0x14000000 ; SA_RESTART | SA_RESTORER
mov dword [RBXPTR(sigaction.sa_flags)], ecx
add rax, sig_restorer - proc_lap_handler
mov qword [RBXPTR(sigaction.sa_restorer)], rax
mov rax, 13 ; sys_rt_sigaction
mov rdi, 2 ; SIGINT
mov rsi, sigaction
mov rsi, rbx
add rsi, sigaction - ts_start
;mov rsi, sigaction
mov rdx, 0 ; NULL
mov r10, 8 ; sig_size
syscall
@ -171,84 +177,91 @@ jne fault
mov rax, 228 ; clock_gettime
mov rdi, 0 ; CLOCK_REALTIME
mov rsi, ts_start
mov rsi, rbx
syscall
mov rax, 1 ; write
mov rdi, 2 ; stderr
mov rsi, startmsg
mov rsi, rbx
add rsi, startmsg - ts_start
mov rdx, startmsglen
syscall
; set value for ts_sleep.tv_nsec given time_res
; div sleep time by 10 for each digits added bellow seconds
mov qword [ts_sleep.tv_sec], 0
mov rax, 100000000
mov r8, [time_res]
mov r9, 10
xor rcx, rcx
mov cl, [RBXPTR(time_res)]
dec cl
test cl, cl
jz setsleep_loopend
mov rsi, 10
xor rdx, rdx
setsleep_loop:
cmp r8, 1
jle setsleep_endloop
div r9
sub r8, 1
jmp setsleep_loop
setsleep_endloop:
mov [ts_sleep.tv_nsec], rax
div rsi
loop setsleep_loop
setsleep_loopend:
mov [RBXPTR(ts_sleep.tv_nsec)], rax
mov r12w, 0x0d02
mov r13, proc_print_time
mov r14, buf ; nanosleep
mov r15, ts_sleep
std ; set DF for string operations
align 16
main_loop:
push 2 ; stderr
push 0xD ; \r
call proc_print_time
; Attempt to read from stdin
call r13 ; proc_print_time
; Attempt to read from stdin (syscall prepared by proc_print_time)
; if something read, enter has been pressed
mov rax, 0
mov rdi, 0
mov rsi, buf
mov rdx, 1
syscall
cmp rax, 0
jge flush_stdin ; flush stdin and exit
test al, al
jns flush_stdin ; flush & exit
mov rax, 35 ; nanosleep
mov rdi, ts_sleep
mov rsi, 0
mov rdi, r15
xor rsi, rsi
syscall
jmp main_loop ; main_loop
flush_stdin:
mov rax, 0
mov rdi, 0
mov rsi, buf
mov rdx, 1
jz newline_exit
xor rax, rax
;xor rdi, rdi ; done in main_loop
;mov rsi, r14
;mov rdx, 1
syscall
cmp rax, 0
je newline_exit
jg flush_stdin
test al, al
jns flush_stdin
xor rbx, rbx ; EXIT OK
jmp exit
newline_exit:
mov rdi, 2 ; stderr
call proc_nl
xor rbx, rbx ; exit OK
jmp exit
mov rdi, 0 ; EXIT OK
;
; Expect rdi to be the return code
; Expect rbx to be the return code
;
exit:
push rdi
; restoring stdin state
mov rax, 72 ; fcntl
xor rdi, rdi
mov rsi, 4 ; F_SETFL
mov rdx, [fcntl_flag]
syscall
cmp rax, 0
je exit_end
pop rdi ; failed to restore
push 1 ; exit FAIL
exit_end:
mov rdi, rbx ; return code
test rax, rax
cmovnz rdi, rax ; exit FAIL
mov rax, 60 ; sys_exit
pop rdi ; return code
syscall
fault:
mov rdi, 2 ; stderr
@ -258,76 +271,74 @@ fault:
mov rdx, faultmsglen
syscall
mov rdi, 1 ; failure
mov rbx, 1 ; failure
jmp exit
newline_exit:
mov rdi, 1
call proc_nl
mov rdi, 0 ; exit OK
jmp exit
;
; Print current time on FD and add a leading char CHR
; push FD & push CHR to set arguments
; argument are in r12w r12b is FD and r12w(h) is CHR
; Warning : DF must be set
;
align 16
proc_print_time:
mov rax, 228 ; clock_gettime
mov rdi, 0 ; CLOCK_REALTIME
xor rdi, rdi ; CLOCK_REALTIME
mov rsi, ts_cur
syscall ; updating ts_cur time
mov rax, [ts_cur.tv_nsec]
sub rax, [ts_start.tv_nsec]
cmp rax, 0 ; Calculating elapsed ns
mov rsi, ts_start.tv_sec
%define RSIPTR(x) rsi + x - ts_start.tv_sec
mov rax, [RSIPTR(ts_cur.tv_nsec)]
sub rax, [ts_start.tv_nsec] ; allign nano sec loop
jge print_time_us_cont
add rax, 1000000000 ; negativ result
sub qword [ts_cur.tv_sec], 1
sub qword [RSIPTR(ts_cur.tv_sec)], 1
print_time_us_cont:
xor rdx, rdx
div qword [ts_sleep.tv_nsec] ; Divide result given time_res
div qword [RSIPTR(ts_sleep.tv_nsec)] ; Divide result given time_res
mov r9, [rsp + 8]
mov byte [timestr+timestrlen-1], r9b ; set last chr from 1st argument
mov bx, r12w
shr bx, 8
mov byte [RSIPTR(timestrend - 1)], bl ; set last chr from 1st argument
; set the nanosec chars (time_res chars) in timestr
mov rbx, 0x2020202020202020
mov rcx, [time_res]
mov r8, 10
mov rcx, [RSIPTR(time_res)]
mov rdi, 10
xor rdx, rdx
align 16 ; should be allready alligned
procpt_loopns:
xor rdx, rdx
div r8
div rdi
or dl, 0x30 ; '0'
shl rbx, 8
mov bl, dl
xchg bl, dl
loop procpt_loopns
mov [timestr+7], rbx
; filling timestr with seconds & minutes chars
mov rax, [ts_cur.tv_sec]
sub rax, [ts_start.tv_sec] ; rax now contain elapsed seconds
mov rax, [RSIPTR(ts_cur.tv_sec)]
sub rax, [RSIPTR(ts_start.tv_sec)] ; rax now contain elapsed seconds
mov r8, 10
mov r9, 6
mov rcx, 10
mov rdi, 6
xor rdx, rdx
div r8
div rcx
mov bh, dl
xor dl, dl
div r9
div rdi
mov bl, dl
or bx, 0x3030
mov word [timestr + 4], bx
xor dl, dl
div r8
div rcx
mov bh, dl
xor dl, dl
div r9
div rdi
mov bl, dl
or bx, 0x3030
mov word [timestr + 1], bx
@ -335,38 +346,53 @@ proc_print_time:
; using rbx to stores the hours string
xor rbx, rbx
mov rcx, HOURSLEN
mov r8, 10
mov rdi, 10
xor dl, dl
align 16
procpt_looph:
xor dl, dl
div r8
div rdi
shl rbx, 8
mov bl, dl
cmp rax, 0
loopne procpt_looph
procpt_looph_end:
xchg bl, dl
test rax, rax
loopnz procpt_looph
mov r8, HOURSLEN - 2
cmp rcx, HOURSLEN - 2
cmovl r8, rcx ; r8 stores hours digit count (at least 2)
cmp rcx, 0
xor rax, rax
mov al, HOURSLEN - 2
cmp cx, HOURSLEN - 2
cmovl ax, cx ; rax stores hours digit count (at least 2)
test cl, cl
jz procpt_looph2_end
procpt_looph2:
align 16
procpt_looph2: ; end rbx left shift before sto
shl rbx, 8
loopne procpt_looph2
procpt_looph2_end:
mov r9, 0x3030303030303030 ; ASCII convertion
or rbx, r9
mov [hours], rbx
mov rdi, 0x3030303030303030 ; ASCII convertion
or rbx, rdi
mov [RSIPTR(hours)], rbx
mov rax, 1 ; write
mov rdi, [rsp + 16] ; fd as 2nd argument
lea rsi, [hours + r8] ; hours start pointer
xor rdi, rdi
mov dil, r12b ; fd as 2nd argument
mov rdx, timestrlen + HOURSLEN
sub rdx, r8 ; timestr + hours len
sub rdx, rax ; timestr + hours len
lea rsi, [RSIPTR(hours + rax)] ; hours start pointer
mov rax, 1 ; write
syscall
test rax, rax
js fault
; ALLIGN TRICK : prepare read syscall for main_loop
xor rax, rax
xor rdi, rdi
mov rsi, r14
mov rdx, 1
ret
%undef RSIPTR
ret 16
;
; sig handler for SIGINT displaying lap count and time on stdout
@ -377,12 +403,16 @@ proc_lap_handler:
mov rsi, cr
mov rdx, 1
syscall ; \r on stderr
test rax, rax
js fault
mov rax, 1
mov rdi, 1
mov rsi, lapsmsg
mov rdx, 4 ; "Lap "
syscall
test rax, rax
js fault
; increment the lapcount str directly
mov rcx, lapcountlen - 1; digit counter starting by the right most
@ -405,15 +435,18 @@ proc_lap_handler:
mov rax, 1
mov rdi, 1 ; stdout
syscall
test rax, rax
js fault
mov rax, 1 ; write
mov rsi, lapsmsg + 3
mov rdx, 3 ; " : "
syscall
test rax, rax
js fault
std ; set DF for string operations
push 1 ; stdout
push 0xA ; \n
mov r12w, 0x0A01 ; \n & stdout
call proc_print_time
ret
@ -428,78 +461,80 @@ sig_restorer:
;
arg_parse:
; Checking argument count
mov rax, [rsp]
cmp rax, 1
mov rcx, [rsp+8] ; argc
mov rsi, [rsp+24] ; argv[1]
mov rdi, badarg_msg
cmp rcx, 1
je arg_ok
cmp rax, 3
cmp rcx, 3
jle parse_r
arg_err: ; badval & badarg jmp here too
mov rax, [rsp+8] ; argv[0] program name
mov rax, [rsp+16] ; argv[0] program name
mov rdi, -1 ; return status
jmp usage
parse_r:
mov rax, [rsp+16] ; 1st arg should be "-r"
mov bl, [rax]
cmp bl, '-'
mov rax, rsi
cmp byte [rsi], '-'
jne badarg
mov bl, [rax+1]
mov bl, [rsi+1]
cmp bl, 'h' ; -h
je arg_err
cmp bl, 'r'
jne badarg
mov bl, [rax+2]
cmp bl, 0
cmp byte [rsi+2], 0
jne arg_nxt ; the value seems to be just after the -r like -r2
nxt_arg:
; the 1st argument is -r the second must be the time_res
; check that the arg exists
mov rax, [rsp]
cmp rax, 3
cmp cl, 3
jne arg_err
mov rax, [rsp+24]
mov rsi, [rsp+32]
jmp arg_cont
arg_nxt:
; check that there is no more args
mov rbx, [rsp]
cmp rbx, 2
cmp cl, 2
jne arg_err
add rax, 2
add rsi, 2
arg_cont:
; rax should point on the value
mov bl, [rax+1]
cmp bl, 0
; rsi should point on the ASCII digit counter
cmp byte [rsi+1], 0
jne badval
xor rbx, rbx
mov bl, [rax]
mov bl, [rsi]
cmp bl, '1'
jl badval
cmp bl, '8'
jg badval
sub bl, '0'
mov [time_res], rbx
jmp arg_ok
xor bl, 0x30 ; '0'
mov [rdi + time_res - badarg_msg], rbx
; print an error message, usage and exit with rax pointing the value
arg_ok:
ret
; print an error message, usage and exit with rax pointing the value and
; rdi badarg_msg ptr
badval:
mov rsi, badval_msg
mov rbx, rsi
lea rsi, [rdi + badval_msg - badarg_msg]
mov rdx, badval_msglen
jmp arg_strerr
; print an error message, usage and exit
badarg:
mov rsi, badarg_msg
mov rbx, rsi
mov rsi, rdi
mov rdx, badarg_msglen
mov rax, [rsp+16]
jmp arg_strerr
; rsi msg ptr, rdx msg len, rax arg ptr
; rsi msg ptr, rdx msg len, rbx arg ptr
arg_strerr:
mov r8, rax
mov rax, 1
mov rdi, 1
syscall
mov rsi, r8
mov rax, r8
mov rsi, rbx
mov rax, rbx
call proc_strlen
mov rax, 1
syscall