5 Commits

Author SHA1 Message Date
  Yann Weber 9e8417b7fb Updated comments, Makefile and REAMDE.txt 5 years ago
  Yann Weber 254c71f687 Add spport for -rX options 5 years ago
  Yann Weber faaf5d2791 Now the sleep time depends on the time_res value 5 years ago
  Yann Weber 055357bfb8 Add argument parsing 5 years ago
  Yann Weber 4f74b3540c Add a variable time_res 5 years ago
3 changed files with 234 additions and 34 deletions
  1. 10
    2
      Makefile
  2. 16
    9
      README.txt
  3. 208
    23
      wtfstopw.asm

+ 10
- 2
Makefile View File

@@ -1,9 +1,17 @@
1
+NASM=nasm
2
+ASFLAGS=-felf64
3
+LDFLAGS=-s -melf_x86_64
4
+
5
+# To build with debugging symbols
6
+#ASFLAGS=-felf64 -F dwarf -g
7
+#LDFLAGS=-melf_x86_64
8
+
1 9
 all: wtfstopw
2 10
 
3 11
 wtfstopw: wtfstopw.o
4
-	ld -s -melf_x86_64 wtfstopw.o -o wtfstopw
12
+	ld $(LDFLAGS) wtfstopw.o -o wtfstopw
5 13
 wtfstopw.o: wtfstopw.asm
6
-	nasm -felf64 wtfstopw.asm
14
+	$(NASM) $(ASFLAGS) wtfstopw.asm
7 15
 	
8 16
 .PHONY: clean
9 17
 

+ 16
- 9
README.txt View File

@@ -3,20 +3,27 @@ WTFStopW : a simple stopwatch
3 3
 
4 4
 Build :
5 5
 -------
6
-
7
-make
8
-
6
+	make
9 7
 or
10
-
11
-nasm -felf64 wtfstopw.asm && ld -s -melf_x86_64 wtfstopw.o -o wtfstopw
8
+	nasm -felf64 wtfstopw.asm
9
+	ld -s -melf_x86_64 wtfstopw.o -o wtfstopw
12 10
 
13 11
 Usage :
14 12
 -------
15
-./wtfstopw
13
+	./wtfstopw [-h] [-r NDIGITS]
14
+Options :
15
+---------
16
+	-h print an help message and exit
17
+	-r number of digits bellow seconds to display, default is 2
16 18
 
17 19
 Interactions :
18 20
 --------------
19
-- press enter to exit or close stdin
20
-- send SIGINT (with kill -2 or ctrl + c) for new lap on stdout
21
-- elapsed time is sent on stderr and laps infos on stdout
21
+	press enter to exit or close stdin
22
+	send SIGINT (with kill -2 or ctrl + c) for new lap on stdout
23
+	elapsed time is sent on stderr and laps infos on stdout
24
+
22 25
 
26
+Build with debugging symbols :
27
+------------------------------
28
+	nasm -g -F dwarf -felf64 -l wtfstopw.lst wtfstopw.asm
29
+	ld -melf_x86_64 wtfstopw.o -o wtfstopw

+ 208
- 23
wtfstopw.asm View File

@@ -17,12 +17,17 @@
17 17
 ;
18 18
 ; A simple precise stopwatch
19 19
 ; Build : nasm -felf64 wtfstopw.asm && ld -s -melf_x86_64 wtfstopw.o -o wtfstopw
20
-; Build Debug : nasm -felf64 -l wtfstopw.lst wtfstopw.asm && ld -melf_x86_64 wtfstopw.o -o wtfstopw
21
-;
22
-; Usage : ./wtfstopw
23
-;	press enter to exit
24
-;	send SIGINT (with kill -2 or ctrl + c) for new lap on stdout
20
+; Build Debug : nasm -g -F dwarf -felf64 -l wtfstopw.lst wtfstopw.asm && ld -melf_x86_64 wtfstopw.o -o wtfstopw
25 21
 ;
22
+; ./wtfstopw [-h] [-r NDIGITS]
23
+; Options :
24
+; 	-h print this help and exit
25
+; 	-r number of digits bellow seconds to display, default is 2
26
+; Interact :
27
+; 	press enter to exit
28
+; 	send SIGINT (with kill -2 ir ctrl + c) for a new lap
29
+
30
+
26 31
 
27 32
 [bits 64]
28 33
 
@@ -32,10 +37,10 @@ STRUC TIMESPEC_STRUC
32 37
 ENDSTRUC
33 38
 
34 39
 
35
-%macro TIMESPEC 1
40
+%macro TIMESPEC 3
36 41
 	%1: ISTRUC TIMESPEC_STRUC
37
-		at TIMESPEC_STRUC.tv_sec, dq 0
38
-		at TIMESPEC_STRUC.tv_nsec, dq 0
42
+		at TIMESPEC_STRUC.tv_sec, dq %2
43
+		at TIMESPEC_STRUC.tv_nsec, dq %3
39 44
 	IEND
40 45
 	%define %1.tv_sec %1+TIMESPEC_STRUC.tv_sec
41 46
 	%define %1.tv_nsec %1+TIMESPEC_STRUC.tv_nsec
@@ -61,17 +66,9 @@ section .data
61 66
 	%define sigaction.sa_restorer sigaction+SIGACTION_STRUC.sa_restorer
62 67
 	%define sigaction.sa_mask sigaction+SIGACTION_STRUC.sa_mask
63 68
 
64
-	TIMESPEC ts_start
65
-	TIMESPEC ts_cur
66
-
67
-	ts_sleep:
68
-		tv_sleep_s dq 0
69
-		tv_sleep_us dq 10000000
70
-
71
-	;; 1/2s sleep
72
-	;ts_sleep:
73
-	;	tv_sleep_s dq 0
74
-	;	tv_sleep_us dq 500000000
69
+	TIMESPEC ts_start, 0, 0
70
+	TIMESPEC ts_cur, 0, 0
71
+	TIMESPEC ts_sleep, 0, 100000000 ; set before mainloop
75 72
 
76 73
 
77 74
 	faultmsg: db "Fault !", 0xA
@@ -81,10 +78,34 @@ section .data
81 78
 	db 0xA
82 79
 	startmsglen: equ $ - startmsg
83 80
 
81
+	usage_pre: db "Usage : "
82
+	usage_prelen: equ $ - usage_pre
83
+
84
+	usage_post: db " [-h] [-r NDIGITS]", 0xA
85
+		db "Options :", 0xA
86
+		db 0x9, "-h print this help and exit", 0xA
87
+		db 0x9, "-r Number of digits bellow seconds, between [1..8]"
88
+		db 0xA
89
+		db "Interactions :", 0xA
90
+		db 0x9, "Press enter or close stdin to exit", 0xA
91
+		db 0x9, "Send SIGINT (with kill -2 or ctrl + c) for a new lap"
92
+		db 0xA
93
+		db 0x9, "Elapsed time is sent on stderr and laps infos on stdout"
94
+		db 0xA
95
+	usage_postlen: equ $ - usage_post
96
+
97
+	badarg_msg: db "Unexpected argument : "
98
+	badarg_msglen: equ $ - badarg_msg
99
+
100
+	badval_msg: db "Value for -r should be in [1..8] but got "
101
+	badval_msglen: equ $ - badval_msg
102
+
84 103
 	hours: db "000000000"
85
-	timestr: db ":00:00.0000    ", 0x0a
104
+	timestr: db ":00:00.0           ", 0x0a
86 105
 	timestrlen: equ $ - timestr
87 106
 
107
+	time_res: dq 2 ; 2 digits bellow seconds can grow to 8
108
+
88 109
 	nl: db 0x0A
89 110
 	buf: db 0
90 111
 
@@ -101,6 +122,10 @@ section .text
101 122
 global _start
102 123
 _start:
103 124
 
125
+; parse arguments and set time_res value
126
+jmp arg_parse
127
+arg_ok:
128
+
104 129
 ; set stdin non blocking
105 130
 xor rdx, rdx
106 131
 xor rdi, rdi
@@ -146,6 +171,21 @@ mov rsi, startmsg
146 171
 mov rdx, startmsglen
147 172
 syscall
148 173
 
174
+; set value for ts_sleep.tv_nsec given time_res
175
+; div sleep time by 10 for each digits added bellow seconds
176
+mov rax, 100000000
177
+mov r8, [time_res]
178
+mov r9, 10
179
+xor rdx, rdx
180
+setsleep_loop:
181
+	cmp r8, 1
182
+	jle setsleep_endloop
183
+	div r9
184
+	sub r8, 1
185
+	jmp setsleep_loop
186
+setsleep_endloop:
187
+mov [ts_sleep.tv_nsec], rax
188
+
149 189
 main_loop:
150 190
 	push 2 ; stderr
151 191
 	push 0x0D ; \r
@@ -254,13 +294,28 @@ proc_print_time:
254 294
 	sub rbx, 1
255 295
 	mov [ts_cur.tv_sec], rbx
256 296
 	print_time_us_cont:
297
+	
298
+	; Divide result given time_res
299
+	mov r10, rax
300
+	mov rax, 1000000000
301
+	mov r9, [time_res]
302
+	mov r8, 10
303
+	xor rdx, rdx
304
+	print_time_respow:
305
+		div r8
306
+		sub r9, 1
307
+		cmp r9, 0
308
+		jg print_time_respow
309
+	mov rcx, rax
310
+	mov rax, r10
257 311
 	xor rdx, rdx
258
-	mov rcx, 100000
259 312
 	div rcx
313
+
260 314
 	; set the us char in timestr
261 315
 	mov r8, timestr
262
-	add r8, 10 ; r8 points on last char before \r
263
-	mov r9, 4 ; r9 count the number of digits
316
+	mov r9, [time_res] ; r9 count the number of digits
317
+	add r8, 6 ; first digits after seconds
318
+	add r8, r9 ; r8 points on last char before \r
264 319
 	print_time_us_loop:
265 320
 		xor rdx, rdx
266 321
 		mov rcx, 10
@@ -415,4 +470,134 @@ sig_restorer:
415 470
 	xor rdi, rdi
416 471
 	syscall
417 472
 
473
+;
474
+;	Argument parsing
475
+;
476
+arg_parse:
477
+	; Checking argument count
478
+	mov rax, [rsp]
479
+	cmp rax, 1
480
+	je arg_ok
481
+	cmp rax, 3
482
+	jle parse_r
483
+	arg_err: ; badval & badarg jmp here too
484
+		mov rax, [rsp+8] ; argv[0] program name
485
+		mov rdi, -1 ; return status
486
+		jmp usage
487
+	parse_r:
488
+	mov rax, [rsp+16] ; 1st arg should be "-r"
489
+	mov bl, [rax]
490
+	cmp bl, '-'
491
+	jne badarg
492
+	mov bl, [rax+1]
493
+	cmp bl, 'h' ; -h
494
+	je arg_err
495
+	cmp bl, 'r'
496
+	jne badarg
497
+	mov bl, [rax+2]
498
+	cmp bl, 0
499
+	jne arg_nxt ; the value seems to be just after the -r like -r2
500
+	nxt_arg:
501
+		; the 1st argument is -r the second must be the time_res
502
+		; check that the arg exists
503
+		mov rax, [rsp]
504
+		cmp rax, 3
505
+		jne arg_err
506
+		mov rax, [rsp+24]
507
+		jmp arg_cont
508
+	arg_nxt:
509
+		; check that there is no more args
510
+		mov rbx, [rsp]
511
+		cmp rbx, 2
512
+		jne arg_err
513
+		add rax, 2
514
+	arg_cont:
515
+	; rax should point on the value
516
+	mov bl, [rax+1]
517
+	cmp bl, 0
518
+	jne badval
519
+	xor rbx, rbx
520
+	mov bl, [rax]
521
+	cmp bl, '1'
522
+	jl badval
523
+	cmp bl, '8'
524
+	jg badval
525
+	sub bl, '0'
526
+	mov [time_res], rbx
527
+	jmp arg_ok
528
+
529
+; print an error message, usage and exit with rax pointing the value
530
+badval:
531
+	mov rsi, badval_msg
532
+	mov rdx, badval_msglen
533
+	jmp arg_strerr
534
+
535
+; print an error message, usage and exit
536
+badarg:
537
+	mov rsi, badarg_msg
538
+	mov rdx, badarg_msglen
539
+	mov rax, [rsp+16]
540
+	jmp arg_strerr
541
+
542
+; rsi msg ptr, rdx msg len, rax arg ptr
543
+arg_strerr:
544
+	mov r8, rax
545
+	mov rax, 1
546
+	mov rdi, 1
547
+	syscall
548
+	mov rsi, r8
549
+	mov rax, r8
550
+	call proc_strlen
551
+	mov rax, 1
552
+	syscall
553
+	mov rax, 1
554
+	mov rsi, nl
555
+	mov rdx, 1
556
+	syscall
557
+	syscall
558
+	jmp arg_err
559
+
560
+;
561
+; Print usage and exit
562
+; 	Except rax to point on programm name and rdi to be the return code
563
+;
564
+usage:
565
+	push rdi
566
+	push rax
567
+
568
+	mov rax, 1 ; write
569
+	mov rdi, 1 ; stdout
570
+	mov rsi, usage_pre
571
+	mov rdx, usage_prelen
572
+	syscall
573
+
574
+	pop rsi
575
+	mov rax, rsi
576
+	call proc_strlen
577
+	mov rax, 1
578
+	syscall
579
+
580
+	mov rax, 1
581
+	mov rsi, usage_post
582
+	mov rdx, usage_postlen
583
+	syscall
584
+
585
+	mov rax, 60
586
+	pop rdi
587
+	syscall
588
+
589
+; With rax pointing on the string, the result will be in rdx
590
+proc_strlen:
591
+	mov r8, rax
592
+	mov r9, r8
593
+	sub r9, 1
594
+	strlen_loop:
595
+		add r9, 1
596
+		mov al, [r9]
597
+		cmp al, 0
598
+		jne strlen_loop
599
+	sub r9, r8
600
+	mov rdx, r9
601
+	ret
602
+
418 603
 .end:

Loading…
Cancel
Save