Compare commits

..

12 commits

Author SHA1 Message Date
891f720dbc Set hours string in a single memory access 2018-09-09 07:36:32 +02:00
cfa1a72edb Factorize timestr initialisation 2018-09-09 05:11:00 +02:00
52da8734d0 Bugfix in timestrlen 2018-09-09 04:42:01 +02:00
fca12d227a Avoid multiple memory access in print_proc_time
For nano sec, sec and min printing
2018-09-09 04:33:11 +02:00
3ec7ad3968 Enhancement in lap handler 2018-09-09 02:53:55 +02:00
862666d41e Enhancement in file header
Moved the macro before .data section
Add a .bss section
Reorganisation of .data section
2018-09-09 02:51:13 +02:00
18814e64ce Renamed labels 2018-09-08 19:29:44 +02:00
e5d5f69a35 Enhancement in proc_print_time
Better comments and op suppression
2018-09-08 18:25:36 +02:00
aaf7fcac2b Removed \r from lap messages 2018-09-08 18:14:39 +02:00
22bc403872 Enhancement in proc_print_time arguments 2018-09-08 17:59:05 +02:00
a12fa7fc53 proc_print_time enhancement 2018-09-08 17:17:28 +02:00
31a4276fa3 Factorisation + enhancement in proc_print_time
Writing a proc_nl function to print a newline on a given fd
Enhancement in argument passing to proc_print_time
2018-09-08 15:28:21 +02:00

View file

@ -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: