Compare commits
10 commits
891f720dbc
...
4432178af9
Author | SHA1 | Date | |
---|---|---|---|
4432178af9 | |||
5929efa54b | |||
8b63d50095 | |||
36abef3e4e | |||
a675c1fd79 | |||
8b427138e0 | |||
511afacfe9 | |||
0da7000028 | |||
9009013637 | |||
a6f66401cb |
1 changed files with 182 additions and 147 deletions
329
wtfstopw.asm
329
wtfstopw.asm
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue