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