|
@@ -1,3 +1,23 @@
|
|
1
|
+;WTFStopW : a simple stopwatch
|
|
2
|
+;Copyright (C) 2018 Weber Yann
|
|
3
|
+;
|
|
4
|
+;This program is free software; you can redistribute it and/or modify
|
|
5
|
+;it under the terms of the GNU General Public License as published by
|
|
6
|
+;the Free Software Foundation; either version 3 of the License, or
|
|
7
|
+;any later version.
|
|
8
|
+;
|
|
9
|
+;This program is distributed in the hope that it will be useful,
|
|
10
|
+;but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+;GNU General Public License for more details.
|
|
13
|
+;
|
|
14
|
+;You should have received a copy of the GNU General Public License
|
|
15
|
+;along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+; A simple precise stopwatch
|
|
18
|
+; Build with :
|
|
19
|
+; nasm -felf64 wtfstopw.asm && ld wtfstopw.o -o wtfstopw
|
|
20
|
+
|
1
|
21
|
[bits 64]
|
2
|
22
|
|
3
|
23
|
section .text
|
|
@@ -7,15 +27,14 @@ _start:
|
7
|
27
|
|
8
|
28
|
; set stdin non blocking
|
9
|
29
|
xor rdx, rdx
|
|
30
|
+xor rdi, rdi
|
10
|
31
|
mov rax, 72 ; fcntl
|
11
|
|
-mov rdi, 0 ; stdin
|
12
|
32
|
mov rsi, 3 ; F_GETFL
|
13
|
33
|
syscall
|
14
|
34
|
mov rdx, rax
|
15
|
35
|
or rdx, 0x800 ; O_NONBLOCK
|
16
|
36
|
dbg:
|
17
|
37
|
mov rax, 72 ; fcntl
|
18
|
|
-mov rdi, 0 ; stdin
|
19
|
38
|
mov rsi, 4 ; F_SETFL
|
20
|
39
|
syscall
|
21
|
40
|
cmp rax, 0
|
|
@@ -28,144 +47,140 @@ syscall
|
28
|
47
|
|
29
|
48
|
|
30
|
49
|
print_time:
|
|
50
|
+ ; updating ts_cur time
|
|
51
|
+ mov rax, 228 ; clock_gettime
|
|
52
|
+ mov rdi, 0 ; CLOCK_REALTIME
|
|
53
|
+ mov rsi, ts_cur
|
|
54
|
+ syscall
|
31
|
55
|
|
32
|
|
-; updating ts_cur time
|
33
|
|
-mov rax, 228 ; clock_gettime
|
34
|
|
-mov rdi, 0 ; CLOCK_REALTIME
|
35
|
|
-mov rsi, ts_cur
|
36
|
|
-syscall
|
|
56
|
+ mov rax, [tv_cur_us]
|
|
57
|
+ mov rbx, [tv_start_us]
|
|
58
|
+ sub rax, rbx
|
|
59
|
+ cmp rax, 0
|
|
60
|
+ jge print_time_us_cont
|
|
61
|
+ ; negativ result
|
|
62
|
+ add rax, 1000000000
|
|
63
|
+ mov rbx, [tv_cur_s]
|
|
64
|
+ sub rbx, 1
|
|
65
|
+ mov [tv_cur_s], rbx
|
|
66
|
+ print_time_us_cont:
|
|
67
|
+ xor rdx, rdx
|
|
68
|
+ mov rcx, 100000
|
|
69
|
+ div rcx
|
|
70
|
+ ; set the us char in timestr
|
|
71
|
+ mov r8, timestr
|
|
72
|
+ add r8, 10 ; r8 points on last char before \r
|
|
73
|
+ mov r9, 4 ; r9 count the number of digits
|
|
74
|
+ print_time_us_loop:
|
|
75
|
+ xor rdx, rdx
|
|
76
|
+ mov rcx, 10
|
|
77
|
+ div rcx
|
|
78
|
+ add dl, 0x30
|
|
79
|
+ mov [r8], dl
|
|
80
|
+ sub r8, 1
|
|
81
|
+ sub r9, 1
|
|
82
|
+ cmp r9, 0
|
|
83
|
+ jg print_time_us_loop
|
|
84
|
+
|
|
85
|
+ ; handling seconds, minutes & hours
|
|
86
|
+ mov rax, [tv_cur_s]
|
|
87
|
+ mov rbx, [tv_start_s]
|
|
88
|
+ sub rax, rbx
|
|
89
|
+ ; rax now contain elapsed seconds
|
|
90
|
+ ; filling timestr with seconds & minutes
|
37
|
91
|
|
38
|
|
-mov rax, [tv_cur_us]
|
39
|
|
-mov rbx, [tv_start_us]
|
40
|
|
-sub rax, rbx
|
41
|
|
-cmp rax, 0
|
42
|
|
-jge print_time_us_cont
|
43
|
|
-; negativ result
|
44
|
|
-add rax, 1000000000
|
45
|
|
-mov rbx, [tv_cur_s]
|
46
|
|
-sub rbx, 1
|
47
|
|
-mov [tv_cur_s], rbx
|
48
|
|
-print_time_us_cont:
|
49
|
|
-xor rdx, rdx
|
50
|
|
-mov rcx, 100000
|
51
|
|
-div rcx
|
52
|
|
-; set the us char in timestr
|
53
|
|
-mov r8, timestr
|
54
|
|
-add r8, 10 ; r8 points on last char before \r
|
55
|
|
-mov r9, 4 ; r9 count the number of digits
|
56
|
|
-print_time_us_loop:
|
57
|
92
|
xor rdx, rdx
|
58
|
93
|
mov rcx, 10
|
59
|
94
|
div rcx
|
60
|
95
|
add dl, 0x30
|
61
|
|
- mov [r8], dl
|
62
|
|
- sub r8, 1
|
63
|
|
- sub r9, 1
|
64
|
|
- cmp r9, 0
|
65
|
|
- jg print_time_us_loop
|
66
|
|
-
|
67
|
|
-; handling seconds, minutes & hours
|
68
|
|
-mov rax, [tv_cur_s]
|
69
|
|
-mov rbx, [tv_start_s]
|
70
|
|
-sub rax, rbx
|
71
|
|
-; rax now contain elapsed seconds
|
72
|
|
-; filling timestr with seconds & minutes
|
|
96
|
+ mov byte [timestr + 5], dl
|
73
|
97
|
|
74
|
|
-xor rdx, rdx
|
75
|
|
-mov rcx, 10
|
76
|
|
-div rcx
|
77
|
|
-push rax
|
78
|
|
-mov rax, rdx
|
79
|
|
-add al, 0x30
|
80
|
|
-mov byte [timestr + 5], al
|
81
|
|
-
|
82
|
|
-pop rax
|
83
|
|
-xor rdx, rdx
|
84
|
|
-mov rcx, 6
|
85
|
|
-div rcx
|
86
|
|
-push rax
|
87
|
|
-mov rax, rdx
|
88
|
|
-add al, 0x30
|
89
|
|
-mov byte [timestr + 4], al
|
90
|
|
-
|
91
|
|
-pop rax
|
92
|
|
-xor rdx, rdx
|
93
|
|
-mov rcx, 10
|
94
|
|
-div rcx
|
95
|
|
-push rax
|
96
|
|
-mov rax, rdx
|
97
|
|
-add al, 0x30
|
98
|
|
-mov byte [timestr + 2], al
|
99
|
|
-
|
100
|
|
-pop rax
|
101
|
|
-xor rdx, rdx
|
102
|
|
-mov rcx, 6
|
103
|
|
-div rcx
|
104
|
|
-push rax
|
105
|
|
-mov rax, rdx
|
106
|
|
-add al, 0x30
|
107
|
|
-mov byte[timestr + 1], al
|
108
|
|
-
|
109
|
|
-; filling the hours buffer
|
110
|
|
-; r8 will contain our digits counter : max is 8
|
111
|
|
-mov r8, 8
|
112
|
|
-pop rax
|
113
|
|
-print_time_hours_loop:
|
114
|
|
- mov rcx, 10
|
|
98
|
+ pop rax
|
115
|
99
|
xor rdx, rdx
|
|
100
|
+ mov rcx, 6
|
116
|
101
|
div rcx
|
117
|
|
- add dl, 0x30
|
118
|
|
- cmp rax, 0
|
119
|
|
- jne print_time_hours_print_mod
|
120
|
|
- cmp rdx, 0
|
121
|
|
- je print_time_hours_loop_end
|
|
102
|
+ push rax
|
|
103
|
+ mov rax, rdx
|
|
104
|
+ add al, 0x30
|
|
105
|
+ mov byte [timestr + 4], al
|
|
106
|
+
|
|
107
|
+ pop rax
|
|
108
|
+ xor rdx, rdx
|
|
109
|
+ mov rcx, 10
|
|
110
|
+ div rcx
|
|
111
|
+ push rax
|
|
112
|
+ mov rax, rdx
|
|
113
|
+ add al, 0x30
|
|
114
|
+ mov byte [timestr + 2], al
|
122
|
115
|
|
123
|
|
- print_time_hours_print_mod:
|
|
116
|
+ pop rax
|
|
117
|
+ xor rdx, rdx
|
|
118
|
+ mov rcx, 6
|
|
119
|
+ div rcx
|
|
120
|
+ push rax
|
|
121
|
+ mov rax, rdx
|
|
122
|
+ add al, 0x30
|
|
123
|
+ mov byte[timestr + 1], al
|
|
124
|
+
|
|
125
|
+ ; filling the hours buffer
|
|
126
|
+ ; r8 will contain our digits counter : max is 8
|
|
127
|
+ mov r8, 8
|
|
128
|
+ pop rax
|
|
129
|
+ print_time_hours_loop:
|
|
130
|
+ mov rcx, 10
|
|
131
|
+ xor rdx, rdx
|
|
132
|
+ div rcx
|
|
133
|
+ add dl, 0x30
|
|
134
|
+ cmp rax, 0
|
|
135
|
+ jne print_time_hours_print_mod
|
|
136
|
+ cmp rdx, 0
|
|
137
|
+ je print_time_hours_loop_end
|
|
138
|
+
|
|
139
|
+ print_time_hours_print_mod:
|
|
140
|
+ mov r9, hours
|
|
141
|
+ add r9, r8
|
|
142
|
+ mov byte [r9], dl
|
|
143
|
+ cmp r8, 0
|
|
144
|
+ je fault
|
|
145
|
+ sub r8, 1
|
|
146
|
+ cmp rax, 0
|
|
147
|
+ jne print_time_hours_loop
|
|
148
|
+ print_time_hours_loop_end:
|
|
149
|
+
|
|
150
|
+ ; print hours + timestr
|
|
151
|
+ add r8, 1
|
|
152
|
+ cmp r8, 7
|
|
153
|
+ jle print_time_hours_cont
|
|
154
|
+ mov r8, 7
|
|
155
|
+ print_time_hours_cont:
|
124
|
156
|
mov r9, hours
|
125
|
157
|
add r9, r8
|
126
|
|
- mov byte [r9], dl
|
127
|
|
- cmp r8, 0
|
128
|
|
- je fault
|
129
|
|
- sub r8, 1
|
130
|
|
- cmp rax, 0
|
131
|
|
- jne print_time_hours_loop
|
132
|
|
-print_time_hours_loop_end:
|
133
|
|
-
|
134
|
|
-; print hours + timestr
|
135
|
|
-add r8, 1
|
136
|
|
-cmp r8, 7
|
137
|
|
-jle print_time_hours_cont
|
138
|
|
-mov r8, 7
|
139
|
|
-print_time_hours_cont:
|
140
|
|
-mov r9, hours
|
141
|
|
-add r9, r8
|
142
|
|
-mov rcx, 9
|
143
|
|
-sub rcx, r8
|
144
|
|
-add rcx, timestrlen
|
145
|
|
-
|
146
|
|
-mov rax, 1 ; write
|
147
|
|
-mov rdi, 1 ; stdout
|
148
|
|
-mov rsi, r9
|
149
|
|
-mov rdx, rcx
|
150
|
|
-syscall
|
|
158
|
+ mov rcx, 9
|
|
159
|
+ sub rcx, r8
|
|
160
|
+ add rcx, timestrlen
|
|
161
|
+
|
|
162
|
+ mov rax, 1 ; write
|
|
163
|
+ mov rdi, 1 ; stdout
|
|
164
|
+ mov rsi, r9
|
|
165
|
+ mov rdx, rcx
|
|
166
|
+ syscall
|
151
|
167
|
|
152
|
|
-; Attempt to read from stdin
|
153
|
|
-; if something read, enter has been pressed
|
154
|
|
-mov rax, 0
|
155
|
|
-mov rdi, 0
|
156
|
|
-mov rsi, buf
|
157
|
|
-mov rdx, 1
|
158
|
|
-syscall
|
159
|
|
-cmp rax, 0
|
160
|
|
-jge flush_stdin ; flush stdin and exit
|
|
168
|
+ ; Attempt to read from stdin
|
|
169
|
+ ; if something read, enter has been pressed
|
|
170
|
+ mov rax, 0
|
|
171
|
+ mov rdi, 0
|
|
172
|
+ mov rsi, buf
|
|
173
|
+ mov rdx, 1
|
|
174
|
+ syscall
|
|
175
|
+ cmp rax, 0
|
|
176
|
+ jge flush_stdin ; flush stdin and exit
|
161
|
177
|
|
162
|
|
-sleep:
|
163
|
|
- mov rax, 35
|
|
178
|
+ mov rax, 35 ; nanosleep
|
164
|
179
|
mov rdi, ts_sleep
|
165
|
180
|
mov rsi, 0
|
166
|
181
|
syscall
|
167
|
182
|
|
168
|
|
-jmp print_time ; main loop
|
|
183
|
+ jmp print_time ; main loop
|
169
|
184
|
|
170
|
185
|
flush_stdin:
|
171
|
186
|
mov rax, 0
|
|
@@ -182,6 +197,16 @@ exit:
|
182
|
197
|
mov rdi, 0 ; OK
|
183
|
198
|
syscall
|
184
|
199
|
fault:
|
|
200
|
+ mov rax, 1 ; write
|
|
201
|
+ mov rdi, 2 ; stderr
|
|
202
|
+ mov rsi, nl
|
|
203
|
+ mov rdx, 1
|
|
204
|
+ syscall
|
|
205
|
+ mov rax, 1
|
|
206
|
+ mov rsi, faultmsg
|
|
207
|
+ mov rdx, faultmsglen
|
|
208
|
+ syscall
|
|
209
|
+
|
185
|
210
|
mov rax, 60 ; sys_exit
|
186
|
211
|
mov rdi, 1 ; failure
|
187
|
212
|
syscall
|
|
@@ -201,6 +226,8 @@ ts_start:
|
201
|
226
|
tv_start_s dq 0
|
202
|
227
|
tv_start_us dq 0
|
203
|
228
|
|
|
229
|
+faultmsg: db "fault", 0xA
|
|
230
|
+faultmsglen: equ $ - faultmsg
|
204
|
231
|
|
205
|
232
|
msg: db "0 Hello, world!", 10
|
206
|
233
|
msglen: equ $ - msg
|
|
@@ -226,5 +253,4 @@ ts_sleep:
|
226
|
253
|
; tv_sleep_s dq 0
|
227
|
254
|
; tv_sleep_us dq 500000000
|
228
|
255
|
|
229
|
|
-
|
230
|
256
|
.end:
|