Compare commits
12 commits
9e8417b7fb
...
891f720dbc
Author | SHA1 | Date | |
---|---|---|---|
891f720dbc | |||
cfa1a72edb | |||
52da8734d0 | |||
fca12d227a | |||
3ec7ad3968 | |||
862666d41e | |||
18814e64ce | |||
e5d5f69a35 | |||
aaf7fcac2b | |||
22bc403872 | |||
a12fa7fc53 | |||
31a4276fa3 |
1 changed files with 158 additions and 200 deletions
358
wtfstopw.asm
358
wtfstopw.asm
|
@ -26,21 +26,20 @@
|
|||
; Interact :
|
||||
; press enter to exit
|
||||
; send SIGINT (with kill -2 ir ctrl + c) for a new lap
|
||||
|
||||
|
||||
|
||||
[bits 64]
|
||||
|
||||
%define O_NONBLOCK 0x800
|
||||
|
||||
STRUC TIMESPEC_STRUC
|
||||
.tv_sec: resq 1
|
||||
.tv_nsec: resq 1
|
||||
ENDSTRUC
|
||||
|
||||
|
||||
%macro TIMESPEC 3
|
||||
%macro TIMESPEC 1
|
||||
%1: ISTRUC TIMESPEC_STRUC
|
||||
at TIMESPEC_STRUC.tv_sec, dq %2
|
||||
at TIMESPEC_STRUC.tv_nsec, dq %3
|
||||
at TIMESPEC_STRUC.tv_sec, resq 1
|
||||
at TIMESPEC_STRUC.tv_nsec, resq 1
|
||||
IEND
|
||||
%define %1.tv_sec %1+TIMESPEC_STRUC.tv_sec
|
||||
%define %1.tv_nsec %1+TIMESPEC_STRUC.tv_nsec
|
||||
|
@ -53,9 +52,9 @@ STRUC SIGACTION_STRUC
|
|||
.sa_mask: resb 128
|
||||
ENDSTRUC
|
||||
|
||||
section .data
|
||||
|
||||
sigaction: ISTRUC SIGACTION_STRUC
|
||||
; from https://www.linuxnasm.be/home/library/lib-includes/signals-inc
|
||||
%macro SIGACTION 1
|
||||
%1: ISTRUC SIGACTION_STRUC
|
||||
at SIGACTION_STRUC.sa_handler, dq 0
|
||||
at SIGACTION_STRUC.sa_flags, dq 0
|
||||
at SIGACTION_STRUC.sa_restorer, dq 0
|
||||
|
@ -65,17 +64,40 @@ section .data
|
|||
%define sigaction.sa_flags sigaction+SIGACTION_STRUC.sa_flags
|
||||
%define sigaction.sa_restorer sigaction+SIGACTION_STRUC.sa_restorer
|
||||
%define sigaction.sa_mask sigaction+SIGACTION_STRUC.sa_mask
|
||||
%endmacro
|
||||
|
||||
TIMESPEC ts_start, 0, 0
|
||||
TIMESPEC ts_cur, 0, 0
|
||||
TIMESPEC ts_sleep, 0, 100000000 ; set before mainloop
|
||||
section .bss
|
||||
align 8
|
||||
TIMESPEC ts_start
|
||||
TIMESPEC ts_cur
|
||||
TIMESPEC ts_sleep
|
||||
buf: resb 1
|
||||
|
||||
section .data
|
||||
|
||||
faultmsg: db "Fault !", 0xA
|
||||
faultmsglen: equ $ - faultmsg
|
||||
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
|
||||
times 0xE db ' '
|
||||
db 0
|
||||
timestrend: align 8
|
||||
timestrlen: equ timestrend - timestr
|
||||
%define HOURSLEN 8
|
||||
|
||||
lapsmsg: db "Lap : "
|
||||
lapsmsglen: equ $ - lapsmsg
|
||||
|
||||
lapcount: times 20 db '0' ; allows storing decimal repr of 1<<64
|
||||
lapcountlen: equ $ - lapcount
|
||||
laplen: dq 2
|
||||
|
||||
startmsg: db "Press Enter or ctrl+d to exit and ctrl+c for new lap."
|
||||
db 0xA
|
||||
db 0xA
|
||||
startmsglen: equ $ - startmsg
|
||||
|
||||
usage_pre: db "Usage : "
|
||||
|
@ -100,23 +122,12 @@ section .data
|
|||
badval_msg: db "Value for -r should be in [1..8] but got "
|
||||
badval_msglen: equ $ - badval_msg
|
||||
|
||||
hours: db "000000000"
|
||||
timestr: db ":00:00.0 ", 0x0a
|
||||
timestrlen: equ $ - timestr
|
||||
|
||||
time_res: dq 2 ; 2 digits bellow seconds can grow to 8
|
||||
faultmsg: db "Fault !", 0xA
|
||||
faultmsglen: equ $ - faultmsg
|
||||
|
||||
nl: db 0x0A
|
||||
buf: db 0
|
||||
cr: db 0xd
|
||||
|
||||
lapsmsg: db 0x0d, "Lap : "
|
||||
lapsmsglen: equ $ - lapsmsg
|
||||
|
||||
lapcount: db "00000000"
|
||||
lapcountlen: equ $ - lapcount
|
||||
laplen: dq 2
|
||||
|
||||
fcntl_flag: dq 0
|
||||
|
||||
section .text
|
||||
global _start
|
||||
|
@ -126,7 +137,7 @@ _start:
|
|||
jmp arg_parse
|
||||
arg_ok:
|
||||
|
||||
; set stdin non blocking
|
||||
; set stdin reads non blocking
|
||||
xor rdx, rdx
|
||||
xor rdi, rdi
|
||||
mov rax, 72 ; fcntl
|
||||
|
@ -134,15 +145,13 @@ mov rsi, 3 ; F_GETFL
|
|||
syscall
|
||||
mov [fcntl_flag], rax
|
||||
mov rdx, rax
|
||||
or rdx, 0x800 ; O_NONBLOCK
|
||||
or rdx, O_NONBLOCK
|
||||
mov rax, 72 ; fcntl
|
||||
mov rsi, 4 ; F_SETFL
|
||||
syscall
|
||||
cmp rax, 0
|
||||
jne fault
|
||||
|
||||
; initializing lapptr
|
||||
|
||||
; preparing SIGINT catch
|
||||
mov rax, proc_lap_handler
|
||||
mov qword [sigaction.sa_handler], rax
|
||||
|
@ -173,6 +182,7 @@ 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
|
||||
|
@ -186,9 +196,10 @@ setsleep_loop:
|
|||
setsleep_endloop:
|
||||
mov [ts_sleep.tv_nsec], rax
|
||||
|
||||
std ; set DF for string operations
|
||||
main_loop:
|
||||
push 2 ; stderr
|
||||
push 0x0D ; \r
|
||||
push 0xD ; \r
|
||||
call proc_print_time
|
||||
|
||||
; Attempt to read from stdin
|
||||
|
@ -240,11 +251,8 @@ exit:
|
|||
pop rdi ; return code
|
||||
syscall
|
||||
fault:
|
||||
mov rax, 1 ; write
|
||||
mov rdi, 2 ; stderr
|
||||
mov rsi, nl
|
||||
mov rdx, 1
|
||||
syscall
|
||||
call proc_nl
|
||||
mov rax, 1
|
||||
mov rsi, faultmsg
|
||||
mov rdx, faultmsglen
|
||||
|
@ -254,11 +262,8 @@ fault:
|
|||
jmp exit
|
||||
|
||||
newline_exit:
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
mov rsi, nl
|
||||
mov rdx, 1
|
||||
syscall
|
||||
call proc_nl
|
||||
|
||||
mov rdi, 0 ; exit OK
|
||||
jmp exit
|
||||
|
@ -266,201 +271,149 @@ newline_exit:
|
|||
;
|
||||
; Print current time on FD and add a leading char CHR
|
||||
; push FD & push CHR to set arguments
|
||||
; Warning : DF must be set
|
||||
;
|
||||
proc_print_time:
|
||||
; push ret addr before arguments
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
push r8
|
||||
push r10
|
||||
push r9
|
||||
|
||||
; updating ts_cur time
|
||||
|
||||
mov rax, 228 ; clock_gettime
|
||||
mov rdi, 0 ; CLOCK_REALTIME
|
||||
mov rsi, ts_cur
|
||||
syscall
|
||||
syscall ; updating ts_cur time
|
||||
|
||||
; Calculating elapsed ns
|
||||
mov rax, [ts_cur.tv_nsec]
|
||||
mov rbx, [ts_start.tv_nsec]
|
||||
sub rax, rbx
|
||||
cmp rax, 0
|
||||
sub rax, [ts_start.tv_nsec]
|
||||
cmp rax, 0 ; Calculating elapsed ns
|
||||
jge print_time_us_cont
|
||||
; negativ result
|
||||
add rax, 1000000000
|
||||
mov rbx, [ts_cur.tv_sec]
|
||||
sub rbx, 1
|
||||
mov [ts_cur.tv_sec], rbx
|
||||
add rax, 1000000000 ; negativ result
|
||||
sub qword [ts_cur.tv_sec], 1
|
||||
print_time_us_cont:
|
||||
|
||||
; Divide result given time_res
|
||||
mov r10, rax
|
||||
mov rax, 1000000000
|
||||
mov r9, [time_res]
|
||||
|
||||
xor rdx, rdx
|
||||
div qword [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
|
||||
|
||||
; set the nanosec chars (time_res chars) in timestr
|
||||
mov rbx, 0x2020202020202020
|
||||
mov rcx, [time_res]
|
||||
mov r8, 10
|
||||
xor rdx, rdx
|
||||
print_time_respow:
|
||||
procpt_loopns:
|
||||
xor rdx, rdx
|
||||
div r8
|
||||
sub r9, 1
|
||||
cmp r9, 0
|
||||
jg print_time_respow
|
||||
mov rcx, rax
|
||||
mov rax, r10
|
||||
xor rdx, rdx
|
||||
div rcx
|
||||
or dl, 0x30 ; '0'
|
||||
shl rbx, 8
|
||||
mov bl, dl
|
||||
loop procpt_loopns
|
||||
mov [timestr+7], rbx
|
||||
|
||||
; set the us char in timestr
|
||||
mov r8, timestr
|
||||
mov r9, [time_res] ; r9 count the number of digits
|
||||
add r8, 6 ; first digits after seconds
|
||||
add r8, r9 ; r8 points on last char before \r
|
||||
print_time_us_loop:
|
||||
xor rdx, rdx
|
||||
mov rcx, 10
|
||||
div rcx
|
||||
add dl, 0x30
|
||||
mov [r8], dl
|
||||
sub r8, 1
|
||||
sub r9, 1
|
||||
cmp r9, 0
|
||||
jg print_time_us_loop
|
||||
|
||||
; handling seconds, minutes & hours
|
||||
; filling timestr with seconds & minutes chars
|
||||
mov rax, [ts_cur.tv_sec]
|
||||
mov rbx, [ts_start.tv_sec]
|
||||
sub rax, rbx
|
||||
; rax now contain elapsed seconds
|
||||
; filling timestr with seconds & minutes
|
||||
sub rax, [ts_start.tv_sec] ; rax now contain elapsed seconds
|
||||
|
||||
mov r8, 10
|
||||
mov r9, 6
|
||||
|
||||
xor rdx, rdx
|
||||
mov rcx, 10
|
||||
div rcx
|
||||
add dl, 0x30
|
||||
mov byte [timestr + 5], dl
|
||||
div r8
|
||||
mov bh, dl
|
||||
xor dl, dl
|
||||
div r9
|
||||
mov bl, dl
|
||||
or bx, 0x3030
|
||||
mov word [timestr + 4], bx
|
||||
|
||||
xor rdx, rdx
|
||||
mov rcx, 6
|
||||
div rcx
|
||||
push rax
|
||||
add dl, 0x30
|
||||
mov byte [timestr + 4], dl
|
||||
xor dl, dl
|
||||
div r8
|
||||
mov bh, dl
|
||||
xor dl, dl
|
||||
div r9
|
||||
mov bl, dl
|
||||
or bx, 0x3030
|
||||
mov word [timestr + 1], bx
|
||||
|
||||
xor rdx, rdx
|
||||
mov rcx, 10
|
||||
div rcx
|
||||
add dl, 0x30
|
||||
mov byte [timestr + 2], dl
|
||||
|
||||
pop rax
|
||||
xor rdx, rdx
|
||||
mov rcx, 6
|
||||
div rcx
|
||||
add dl, 0x30
|
||||
mov byte[timestr + 1], dl
|
||||
|
||||
; filling the hours buffer
|
||||
; r8 will contain our digits counter : max is 8
|
||||
mov r8, 8
|
||||
print_time_hours_loop:
|
||||
mov rcx, 10
|
||||
xor rdx, rdx
|
||||
div rcx
|
||||
add dl, 0x30
|
||||
; using rbx to stores the hours string
|
||||
xor rbx, rbx
|
||||
mov rcx, HOURSLEN
|
||||
mov r8, 10
|
||||
procpt_looph:
|
||||
xor dl, dl
|
||||
div r8
|
||||
shl rbx, 8
|
||||
mov bl, dl
|
||||
cmp rax, 0
|
||||
jne print_time_hours_print_mod
|
||||
cmp rdx, 0
|
||||
je print_time_hours_loop_end
|
||||
loopne procpt_looph
|
||||
procpt_looph_end:
|
||||
|
||||
print_time_hours_print_mod:
|
||||
mov r9, hours
|
||||
add r9, r8
|
||||
mov byte [r9], dl
|
||||
cmp r8, 0
|
||||
je fault
|
||||
sub r8, 1
|
||||
cmp rax, 0
|
||||
jne print_time_hours_loop
|
||||
print_time_hours_loop_end:
|
||||
mov r8, HOURSLEN - 2
|
||||
cmp rcx, HOURSLEN - 2
|
||||
cmovl r8, rcx ; r8 stores hours digit count (at least 2)
|
||||
cmp rcx, 0
|
||||
jz procpt_looph2_end
|
||||
procpt_looph2:
|
||||
shl rbx, 8
|
||||
loopne procpt_looph2
|
||||
procpt_looph2_end:
|
||||
|
||||
; print hours + timestr
|
||||
add r8, 1
|
||||
cmp r8, 7
|
||||
jle print_time_hours_cont
|
||||
mov r8, 7 ; maximum value for r8
|
||||
print_time_hours_cont:
|
||||
mov r9, hours
|
||||
add r9, r8
|
||||
mov rcx, 9
|
||||
sub rcx, r8 ; rcx is hours size
|
||||
add rcx, timestrlen ; add to timestrlen
|
||||
|
||||
; Set leading char
|
||||
pop r10
|
||||
mov byte [timestr+timestrlen-1], r10b
|
||||
mov r9, 0x3030303030303030 ; ASCII convertion
|
||||
or rbx, r9
|
||||
mov [hours], rbx
|
||||
|
||||
mov rax, 1 ; write
|
||||
pop r10 ; print_time FD arg
|
||||
mov rdi, r10 ; print_time arg
|
||||
mov rsi, r9 ; start hours pointer
|
||||
mov rdx, rcx ; size to timestr end
|
||||
mov rdi, [rsp + 16] ; fd as 2nd argument
|
||||
lea rsi, [hours + r8] ; hours start pointer
|
||||
mov rdx, timestrlen + HOURSLEN
|
||||
sub rdx, r8 ; timestr + hours len
|
||||
syscall
|
||||
|
||||
ret
|
||||
ret 16
|
||||
|
||||
;
|
||||
; sig handler for SIGINT displaying lap count and time on stdout
|
||||
;
|
||||
proc_lap_handler:
|
||||
mov rax, 1
|
||||
mov rdi, 2
|
||||
mov rsi, cr
|
||||
mov rdx, 1
|
||||
syscall ; \r on stderr
|
||||
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
mov rsi, lapsmsg
|
||||
mov rdx, 5 ; "Lap "
|
||||
mov rdx, 4 ; "Lap "
|
||||
syscall
|
||||
|
||||
; increment the lapcount str directly
|
||||
mov rbx, lapcount ; first digit ptr
|
||||
add rbx, lapcountlen ; rightmost digit ptr
|
||||
sub rbx, 1
|
||||
mov r8, 1 ; counter
|
||||
lap_handler_inc_lap:
|
||||
mov r10b, [rbx]
|
||||
cmp r10b, 0x39 ; '9'
|
||||
jl lap_handler_inc_end
|
||||
mov rcx, lapcountlen - 1; digit counter starting by the right most
|
||||
proclap_loop:
|
||||
cmp byte [lapcount + rcx], '9'
|
||||
jl proclap_loopend
|
||||
mov byte [lapcount + rcx], '0' ; set current digit to '0'
|
||||
loop proclap_loop
|
||||
proclap_loopend:
|
||||
add byte [lapcount + rcx], 1 ; increment current digit
|
||||
|
||||
add r8, 1
|
||||
cmp r8, [laplen]
|
||||
jl lap_handler_laplen_noupd
|
||||
mov [laplen], r8 ; update laplen
|
||||
|
||||
lap_handler_laplen_noupd:
|
||||
mov byte [rbx], 0x30 ; set current digit to '0'
|
||||
sub rbx, 1
|
||||
cmp rbx, lapcount
|
||||
jl fault
|
||||
jmp lap_handler_inc_lap
|
||||
lap_handler_inc_end:
|
||||
add r10b, 1
|
||||
mov [rbx], r10b
|
||||
mov rdx, lapcountlen
|
||||
sub rdx, rcx
|
||||
cmp rdx, [laplen] ; update laplen if needed
|
||||
cmovl rdx, [laplen]
|
||||
mov [laplen], rdx
|
||||
mov rsi, lapcount + lapcountlen
|
||||
sub rsi, rdx
|
||||
|
||||
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
mov rdx, [laplen]
|
||||
mov rsi, lapcount
|
||||
add rsi, lapcountlen
|
||||
sub rsi, rdx ; leftmost digit ptr
|
||||
mov rdi, 1 ; stdout
|
||||
syscall
|
||||
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
mov rsi, lapsmsg + 4
|
||||
mov rax, 1 ; write
|
||||
mov rsi, lapsmsg + 3
|
||||
mov rdx, 3 ; " : "
|
||||
syscall
|
||||
|
||||
std ; set DF for string operations
|
||||
push 1 ; stdout
|
||||
push 0x0A ; \n
|
||||
push 0xA ; \n
|
||||
call proc_print_time
|
||||
|
||||
ret
|
||||
|
@ -550,11 +503,8 @@ arg_strerr:
|
|||
call proc_strlen
|
||||
mov rax, 1
|
||||
syscall
|
||||
mov rax, 1
|
||||
mov rsi, nl
|
||||
mov rdx, 1
|
||||
syscall
|
||||
syscall
|
||||
call proc_nl
|
||||
call proc_nl
|
||||
jmp arg_err
|
||||
|
||||
;
|
||||
|
@ -590,9 +540,9 @@ usage:
|
|||
proc_strlen:
|
||||
mov r8, rax
|
||||
mov r9, r8
|
||||
sub r9, 1
|
||||
dec r9
|
||||
strlen_loop:
|
||||
add r9, 1
|
||||
inc r9
|
||||
mov al, [r9]
|
||||
cmp al, 0
|
||||
jne strlen_loop
|
||||
|
@ -600,4 +550,12 @@ proc_strlen:
|
|||
mov rdx, r9
|
||||
ret
|
||||
|
||||
; with rdi the fd
|
||||
proc_nl:
|
||||
mov rax, 1
|
||||
mov rsi, nl
|
||||
mov rdx, 1
|
||||
syscall
|
||||
ret
|
||||
|
||||
.end:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue