12 Commits

Author SHA1 Message Date
  Yann Weber 891f720dbc Set hours string in a single memory access 5 years ago
  Yann Weber cfa1a72edb Factorize timestr initialisation 5 years ago
  Yann Weber 52da8734d0 Bugfix in timestrlen 5 years ago
  Yann Weber fca12d227a Avoid multiple memory access in print_proc_time 5 years ago
  Yann Weber 3ec7ad3968 Enhancement in lap handler 5 years ago
  Yann Weber 862666d41e Enhancement in file header 5 years ago
  Yann Weber 18814e64ce Renamed labels 5 years ago
  Yann Weber e5d5f69a35 Enhancement in proc_print_time 5 years ago
  Yann Weber aaf7fcac2b Removed \r from lap messages 5 years ago
  Yann Weber 22bc403872 Enhancement in proc_print_time arguments 5 years ago
  Yann Weber a12fa7fc53 proc_print_time enhancement 5 years ago
  Yann Weber 31a4276fa3 Factorisation + enhancement in proc_print_time 5 years ago
1 changed files with 162 additions and 204 deletions
  1. 162
    204
      wtfstopw.asm

+ 162
- 204
wtfstopw.asm View File

@@ -26,21 +26,20 @@
26 26
 ; Interact :
27 27
 ; 	press enter to exit
28 28
 ; 	send SIGINT (with kill -2 ir ctrl + c) for a new lap
29
-
30
-
31
-
32 29
 [bits 64]
33 30
 
31
+%define O_NONBLOCK 0x800
32
+
34 33
 STRUC TIMESPEC_STRUC
35 34
 	.tv_sec: resq 1
36 35
 	.tv_nsec: resq 1
37 36
 ENDSTRUC
38 37
 
39 38
 
40
-%macro TIMESPEC 3
39
+%macro TIMESPEC 1
41 40
 	%1: ISTRUC TIMESPEC_STRUC
42
-		at TIMESPEC_STRUC.tv_sec, dq %2
43
-		at TIMESPEC_STRUC.tv_nsec, dq %3
41
+		at TIMESPEC_STRUC.tv_sec, resq 1
42
+		at TIMESPEC_STRUC.tv_nsec, resq 1
44 43
 	IEND
45 44
 	%define %1.tv_sec %1+TIMESPEC_STRUC.tv_sec
46 45
 	%define %1.tv_nsec %1+TIMESPEC_STRUC.tv_nsec
@@ -53,9 +52,9 @@ STRUC SIGACTION_STRUC
53 52
 	.sa_mask:         resb      128
54 53
 ENDSTRUC
55 54
 
56
-section .data
57
-
58
-	sigaction: ISTRUC SIGACTION_STRUC
55
+; from https://www.linuxnasm.be/home/library/lib-includes/signals-inc
56
+%macro SIGACTION 1
57
+	%1: ISTRUC SIGACTION_STRUC
59 58
 		at  SIGACTION_STRUC.sa_handler, dq 0
60 59
 		at  SIGACTION_STRUC.sa_flags, dq 0
61 60
 		at  SIGACTION_STRUC.sa_restorer, dq 0
@@ -65,17 +64,40 @@ section .data
65 64
 	%define sigaction.sa_flags sigaction+SIGACTION_STRUC.sa_flags
66 65
 	%define sigaction.sa_restorer sigaction+SIGACTION_STRUC.sa_restorer
67 66
 	%define sigaction.sa_mask sigaction+SIGACTION_STRUC.sa_mask
67
+%endmacro
68 68
 
69
-	TIMESPEC ts_start, 0, 0
70
-	TIMESPEC ts_cur, 0, 0
71
-	TIMESPEC ts_sleep, 0, 100000000 ; set before mainloop
69
+section .bss
70
+align 8
71
+	TIMESPEC ts_start
72
+	TIMESPEC ts_cur
73
+	TIMESPEC ts_sleep
74
+	buf: resb 1
72 75
 
76
+section .data
73 77
 
74
-	faultmsg: db "Fault !", 0xA
75
-	faultmsglen: equ $ - faultmsg
78
+	time_res: dq 2 ; 2 digits bellow seconds can grow to 8
79
+	fcntl_flag: dq 0
80
+	SIGACTION sigaction
81
+
82
+	align 8
83
+	hours: times 8 db '0' ; 8 digits is the max for hours
84
+	timestr: db ":00:00." 
85
+		times 8 db '0' ; 8 digits for nanoseconds
86
+		times 0xE db ' '
87
+		db 0
88
+	timestrend: align 8
89
+	timestrlen: equ timestrend - timestr
90
+	%define HOURSLEN 8
91
+
92
+	lapsmsg: db "Lap : "
93
+	lapsmsglen: equ $ - lapsmsg
94
+
95
+	lapcount: times 20 db '0' ; allows storing decimal repr of 1<<64
96
+	lapcountlen: equ $ - lapcount
97
+	laplen: dq 2
76 98
 
77 99
 	startmsg: db "Press Enter or ctrl+d to exit and ctrl+c for new lap."
78
-	db 0xA
100
+		db 0xA
79 101
 	startmsglen: equ $ - startmsg
80 102
 
81 103
 	usage_pre: db "Usage : "
@@ -100,23 +122,12 @@ section .data
100 122
 	badval_msg: db "Value for -r should be in [1..8] but got "
101 123
 	badval_msglen: equ $ - badval_msg
102 124
 
103
-	hours: db "000000000"
104
-	timestr: db ":00:00.0           ", 0x0a
105
-	timestrlen: equ $ - timestr
106
-
107
-	time_res: dq 2 ; 2 digits bellow seconds can grow to 8
125
+	faultmsg: db "Fault !", 0xA
126
+	faultmsglen: equ $ - faultmsg
108 127
 
109 128
 	nl: db 0x0A
110
-	buf: db 0
129
+	cr: db 0xd
111 130
 
112
-	lapsmsg: db 0x0d, "Lap : "
113
-	lapsmsglen: equ $ - lapsmsg
114
-
115
-	lapcount: db "00000000"
116
-	lapcountlen: equ $ - lapcount
117
-	laplen: dq 2
118
-
119
-	fcntl_flag: dq 0
120 131
 
121 132
 section .text
122 133
 global _start
@@ -126,7 +137,7 @@ _start:
126 137
 jmp arg_parse
127 138
 arg_ok:
128 139
 
129
-; set stdin non blocking
140
+; set stdin reads non blocking
130 141
 xor rdx, rdx
131 142
 xor rdi, rdi
132 143
 mov rax, 72 ; fcntl
@@ -134,15 +145,13 @@ mov rsi, 3 ; F_GETFL
134 145
 syscall
135 146
 mov [fcntl_flag], rax
136 147
 mov rdx, rax
137
-or rdx, 0x800 ; O_NONBLOCK
148
+or rdx, O_NONBLOCK
138 149
 mov rax, 72 ; fcntl
139 150
 mov rsi, 4 ; F_SETFL
140 151
 syscall
141 152
 cmp rax, 0
142 153
 jne fault
143 154
 
144
-; initializing lapptr
145
-
146 155
 ; preparing SIGINT catch
147 156
 mov rax, proc_lap_handler
148 157
 mov qword [sigaction.sa_handler], rax
@@ -173,6 +182,7 @@ syscall
173 182
 
174 183
 ; set value for ts_sleep.tv_nsec given time_res
175 184
 ; div sleep time by 10 for each digits added bellow seconds
185
+mov qword [ts_sleep.tv_sec], 0
176 186
 mov rax, 100000000
177 187
 mov r8, [time_res]
178 188
 mov r9, 10
@@ -186,9 +196,10 @@ setsleep_loop:
186 196
 setsleep_endloop:
187 197
 mov [ts_sleep.tv_nsec], rax
188 198
 
199
+std ; set DF for string operations
189 200
 main_loop:
190 201
 	push 2 ; stderr
191
-	push 0x0D ; \r
202
+	push 0xD ; \r
192 203
 	call proc_print_time
193 204
 
194 205
 	; Attempt to read from stdin
@@ -240,11 +251,8 @@ exit:
240 251
 	pop rdi ; return code
241 252
 	syscall
242 253
 fault:
243
-	mov rax, 1 ; write
244 254
 	mov rdi, 2 ; stderr
245
-	mov rsi, nl
246
-	mov rdx, 1
247
-	syscall
255
+	call proc_nl
248 256
 	mov rax, 1
249 257
 	mov rsi, faultmsg
250 258
 	mov rdx, faultmsglen
@@ -254,11 +262,8 @@ fault:
254 262
 	jmp exit
255 263
 
256 264
 newline_exit:
257
-	mov rax, 1
258 265
 	mov rdi, 1
259
-	mov rsi, nl
260
-	mov rdx, 1
261
-	syscall
266
+	call proc_nl
262 267
 
263 268
 	mov rdi, 0 ; exit OK
264 269
 	jmp exit
@@ -266,201 +271,149 @@ newline_exit:
266 271
 ;
267 272
 ; Print current time on FD and add a leading char CHR
268 273
 ; push FD & push CHR to set arguments
274
+; 	Warning : DF must be set
269 275
 ;
270 276
 proc_print_time:
271
-	; push ret addr before arguments
272
-	pop r8
273
-	pop r9
274
-	pop r10
275
-	push r8
276
-	push r10
277
-	push r9
278
-
279
-	; updating ts_cur time
277
+	
280 278
 	mov rax, 228 ; clock_gettime
281 279
 	mov rdi, 0 ; CLOCK_REALTIME
282 280
 	mov rsi, ts_cur
283
-	syscall
281
+	syscall ; updating ts_cur time
284 282
 
285
-	; Calculating elapsed ns
286 283
 	mov rax, [ts_cur.tv_nsec]
287
-	mov rbx, [ts_start.tv_nsec]
288
-	sub rax, rbx
289
-	cmp rax, 0
284
+	sub rax, [ts_start.tv_nsec]
285
+	cmp rax, 0 ; Calculating elapsed ns
290 286
 	jge print_time_us_cont
291
-	; negativ result
292
-	add rax, 1000000000
293
-	mov rbx, [ts_cur.tv_sec]
294
-	sub rbx, 1
295
-	mov [ts_cur.tv_sec], rbx
287
+	add rax, 1000000000 ; negativ result
288
+	sub qword [ts_cur.tv_sec], 1
296 289
 	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
290
+
311 291
 	xor rdx, rdx
312
-	div rcx
313
-
314
-	; set the us char in timestr
315
-	mov r8, timestr
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
319
-	print_time_us_loop:
292
+	div qword [ts_sleep.tv_nsec] ; Divide result given time_res
293
+
294
+	mov r9, [rsp + 8]
295
+	mov byte [timestr+timestrlen-1], r9b ; set last chr from 1st argument
296
+
297
+	; set the nanosec chars (time_res chars) in timestr
298
+	mov rbx, 0x2020202020202020
299
+	mov rcx, [time_res]
300
+	mov r8, 10
301
+	procpt_loopns:
320 302
 		xor rdx, rdx
321
-		mov rcx, 10
322
-		div rcx
323
-		add dl, 0x30
324
-		mov [r8], dl
325
-		sub r8, 1
326
-		sub r9, 1
327
-		cmp r9, 0
328
-		jg print_time_us_loop
329
-
330
-	; handling seconds, minutes & hours
331
-	mov rax, [ts_cur.tv_sec]
332
-	mov rbx, [ts_start.tv_sec]
333
-	sub rax, rbx
334
-	; rax now contain elapsed seconds
335
-	; filling timestr with seconds & minutes
303
+		div r8
304
+		or dl, 0x30 ; '0'
305
+		shl rbx, 8
306
+		mov bl, dl
307
+		loop procpt_loopns
308
+	mov [timestr+7], rbx
336 309
 
337
-	xor rdx, rdx
338
-	mov rcx, 10
339
-	div rcx
340
-	add dl, 0x30
341
-	mov byte [timestr + 5], dl
310
+	; filling timestr with seconds & minutes chars
311
+	mov rax, [ts_cur.tv_sec]
312
+	sub rax, [ts_start.tv_sec] ; rax now contain elapsed seconds
342 313
 
343
-	xor rdx, rdx
344
-	mov rcx, 6
345
-	div rcx
346
-	push rax
347
-	add dl, 0x30
348
-	mov byte [timestr + 4], dl
314
+	mov r8, 10
315
+	mov r9, 6
349 316
 
350 317
 	xor rdx, rdx
351
-	mov rcx, 10
352
-	div rcx
353
-	add dl, 0x30
354
-	mov byte [timestr + 2], dl
318
+	div r8
319
+	mov bh, dl
320
+	xor dl, dl
321
+	div r9
322
+	mov bl, dl
323
+	or bx, 0x3030
324
+	mov word [timestr + 4], bx
325
+
326
+	xor dl, dl
327
+	div r8
328
+	mov bh, dl
329
+	xor dl, dl
330
+	div r9
331
+	mov bl, dl
332
+	or bx, 0x3030
333
+	mov word [timestr + 1], bx
355 334
 
356
-	pop rax
357
-	xor rdx, rdx
358
-	mov rcx, 6
359
-	div rcx
360
-	add dl, 0x30
361
-	mov byte[timestr + 1], dl
362
-
363
-	; filling the hours buffer
364
-	; r8 will contain our digits counter : max is 8
365
-	mov r8, 8
366
-	print_time_hours_loop:
367
-		mov rcx, 10
368
-		xor rdx, rdx
369
-		div rcx
370
-		add dl, 0x30
371
-		cmp rax, 0
372
-		jne print_time_hours_print_mod
373
-		cmp rdx, 0
374
-		je print_time_hours_loop_end
375
-
376
-		print_time_hours_print_mod:
377
-		mov r9, hours
378
-		add r9, r8
379
-		mov byte [r9], dl
380
-		cmp r8, 0
381
-		je fault
382
-		sub r8, 1
335
+	; using rbx to stores the hours string
336
+	xor rbx, rbx
337
+	mov rcx, HOURSLEN
338
+	mov r8, 10
339
+	procpt_looph:
340
+		xor dl, dl
341
+		div r8
342
+		shl rbx, 8
343
+		mov bl, dl
383 344
 		cmp rax, 0
384
-		jne print_time_hours_loop
385
-	print_time_hours_loop_end:
386
-
387
-	; print hours + timestr
388
-	add r8, 1
389
-	cmp r8, 7
390
-	jle print_time_hours_cont
391
-	mov r8, 7 ; maximum value for r8
392
-	print_time_hours_cont:
393
-	mov r9, hours
394
-	add r9, r8
395
-	mov rcx, 9
396
-	sub rcx, r8 ; rcx is hours size 
397
-	add rcx, timestrlen ; add to timestrlen
398
-
399
-	; Set leading char
400
-	pop r10
401
-	mov byte [timestr+timestrlen-1], r10b
345
+		loopne procpt_looph
346
+	procpt_looph_end:
347
+
348
+	mov r8, HOURSLEN - 2
349
+	cmp rcx, HOURSLEN - 2
350
+	cmovl r8, rcx ; r8 stores hours digit count (at least 2)
351
+	cmp rcx, 0
352
+	jz procpt_looph2_end
353
+	procpt_looph2:
354
+		shl rbx, 8
355
+		loopne procpt_looph2
356
+	procpt_looph2_end:
357
+
358
+	mov r9, 0x3030303030303030 ; ASCII convertion
359
+	or rbx, r9
360
+	mov [hours], rbx
402 361
 
403 362
 	mov rax, 1 ; write
404
-	pop r10 ; print_time FD arg
405
-	mov rdi, r10 ; print_time arg
406
-	mov rsi, r9 ; start hours pointer
407
-	mov rdx, rcx ; size to timestr end
363
+	mov rdi, [rsp + 16] ; fd as 2nd argument
364
+	lea rsi, [hours + r8] ; hours start pointer
365
+	mov rdx, timestrlen + HOURSLEN
366
+	sub rdx, r8 ; timestr + hours len
408 367
 	syscall
409 368
 
410
-	ret
369
+	ret 16
411 370
 
412 371
 ;
413 372
 ;	sig handler for SIGINT displaying lap count and time on stdout
414 373
 ;
415 374
 proc_lap_handler:
375
+	mov rax, 1
376
+	mov rdi, 2
377
+	mov rsi, cr
378
+	mov rdx, 1
379
+	syscall ; \r on stderr
380
+
416 381
 	mov rax, 1
417 382
 	mov rdi, 1
418 383
 	mov rsi, lapsmsg
419
-	mov rdx, 5 ; "Lap "
384
+	mov rdx, 4 ; "Lap "
420 385
 	syscall
421 386
 
422 387
 	; increment the lapcount str directly
423
-	mov rbx, lapcount ; first digit ptr
424
-	add rbx, lapcountlen ; rightmost digit ptr
425
-	sub rbx, 1
426
-	mov r8, 1 ; counter
427
-	lap_handler_inc_lap:
428
-		mov r10b, [rbx]
429
-		cmp r10b, 0x39 ; '9'
430
-		jl lap_handler_inc_end
431
-
432
-		add r8, 1
433
-		cmp r8, [laplen]
434
-		jl lap_handler_laplen_noupd
435
-		mov [laplen], r8 ; update laplen
436
-
437
-		lap_handler_laplen_noupd:
438
-		mov byte [rbx], 0x30 ; set current digit to '0'
439
-		sub rbx, 1
440
-		cmp rbx, lapcount
441
-		jl fault
442
-		jmp lap_handler_inc_lap
443
-	lap_handler_inc_end:
444
-		add r10b, 1
445
-		mov [rbx], r10b
388
+	mov rcx, lapcountlen - 1; digit counter starting by the right most
389
+	proclap_loop:
390
+		cmp byte [lapcount + rcx], '9'
391
+		jl proclap_loopend
392
+		mov byte [lapcount + rcx], '0' ; set current digit to '0'
393
+		loop proclap_loop
394
+	proclap_loopend:
395
+	add byte [lapcount + rcx], 1 ; increment current digit
396
+
397
+	mov rdx, lapcountlen
398
+	sub rdx, rcx
399
+	cmp rdx, [laplen] ; update laplen if needed
400
+	cmovl rdx, [laplen]
401
+	mov [laplen], rdx
402
+	mov rsi, lapcount + lapcountlen
403
+	sub rsi, rdx
446 404
 	
447
-
448 405
 	mov rax, 1
449
-	mov rdi, 1
450
-	mov rdx, [laplen]
451
-	mov rsi, lapcount
452
-	add rsi, lapcountlen
453
-	sub rsi, rdx ; leftmost digit ptr
406
+	mov rdi, 1 ; stdout
454 407
 	syscall
455 408
 
456
-	mov rax, 1
457
-	mov rdi, 1
458
-	mov rsi, lapsmsg + 4
409
+	mov rax, 1 ; write
410
+	mov rsi, lapsmsg + 3
459 411
 	mov rdx, 3 ; " : "
460 412
 	syscall
461 413
 
414
+	std ; set DF for string operations
462 415
 	push 1 ; stdout
463
-	push 0x0A ; \n
416
+	push 0xA ; \n
464 417
 	call proc_print_time
465 418
 
466 419
 	ret
@@ -550,11 +503,8 @@ arg_strerr:
550 503
 	call proc_strlen
551 504
 	mov rax, 1
552 505
 	syscall
553
-	mov rax, 1
554
-	mov rsi, nl
555
-	mov rdx, 1
556
-	syscall
557
-	syscall
506
+	call proc_nl
507
+	call proc_nl
558 508
 	jmp arg_err
559 509
 
560 510
 ;
@@ -590,9 +540,9 @@ usage:
590 540
 proc_strlen:
591 541
 	mov r8, rax
592 542
 	mov r9, r8
593
-	sub r9, 1
543
+	dec r9
594 544
 	strlen_loop:
595
-		add r9, 1
545
+		inc r9
596 546
 		mov al, [r9]
597 547
 		cmp al, 0
598 548
 		jne strlen_loop
@@ -600,4 +550,12 @@ proc_strlen:
600 550
 	mov rdx, r9
601 551
 	ret
602 552
 
553
+; with rdi the fd
554
+proc_nl:
555
+	mov rax, 1
556
+	mov rsi, nl
557
+	mov rdx, 1
558
+	syscall
559
+	ret
560
+
603 561
 .end:

Loading…
Cancel
Save