WTFStopW : a simple stopwatch
x86-64
nasm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wtfstopw.asm 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. ; A simple precise stopwatch
  17. ; Build with :
  18. ; nasm -felf64 wtfstopw.asm && ld wtfstopw.o -o wtfstopw
  19. [bits 64]
  20. section .text
  21. global _start
  22. _start:
  23. ; set stdin non blocking
  24. xor rdx, rdx
  25. xor rdi, rdi
  26. mov rax, 72 ; fcntl
  27. mov rsi, 3 ; F_GETFL
  28. syscall
  29. mov rdx, rax
  30. or rdx, 0x800 ; O_NONBLOCK
  31. dbg:
  32. mov rax, 72 ; fcntl
  33. mov rsi, 4 ; F_SETFL
  34. syscall
  35. cmp rax, 0
  36. jne fault
  37. mov rax, 228 ; clock_gettime
  38. mov rdi, 0 ; CLOCK_REALTIME
  39. mov rsi, ts_start
  40. syscall
  41. print_time:
  42. ; updating ts_cur time
  43. mov rax, 228 ; clock_gettime
  44. mov rdi, 0 ; CLOCK_REALTIME
  45. mov rsi, ts_cur
  46. syscall
  47. mov rax, [tv_cur_us]
  48. mov rbx, [tv_start_us]
  49. sub rax, rbx
  50. cmp rax, 0
  51. jge print_time_us_cont
  52. ; negativ result
  53. add rax, 1000000000
  54. mov rbx, [tv_cur_s]
  55. sub rbx, 1
  56. mov [tv_cur_s], rbx
  57. print_time_us_cont:
  58. xor rdx, rdx
  59. mov rcx, 100000
  60. div rcx
  61. ; set the us char in timestr
  62. mov r8, timestr
  63. add r8, 10 ; r8 points on last char before \r
  64. mov r9, 4 ; r9 count the number of digits
  65. print_time_us_loop:
  66. xor rdx, rdx
  67. mov rcx, 10
  68. div rcx
  69. add dl, 0x30
  70. mov [r8], dl
  71. sub r8, 1
  72. sub r9, 1
  73. cmp r9, 0
  74. jg print_time_us_loop
  75. ; handling seconds, minutes & hours
  76. mov rax, [tv_cur_s]
  77. mov rbx, [tv_start_s]
  78. sub rax, rbx
  79. ; rax now contain elapsed seconds
  80. ; filling timestr with seconds & minutes
  81. xor rdx, rdx
  82. mov rcx, 10
  83. div rcx
  84. add dl, 0x30
  85. mov byte [timestr + 5], dl
  86. pop rax
  87. xor rdx, rdx
  88. mov rcx, 6
  89. div rcx
  90. push rax
  91. mov rax, rdx
  92. add al, 0x30
  93. mov byte [timestr + 4], al
  94. pop rax
  95. xor rdx, rdx
  96. mov rcx, 10
  97. div rcx
  98. push rax
  99. mov rax, rdx
  100. add al, 0x30
  101. mov byte [timestr + 2], al
  102. pop rax
  103. xor rdx, rdx
  104. mov rcx, 6
  105. div rcx
  106. push rax
  107. mov rax, rdx
  108. add al, 0x30
  109. mov byte[timestr + 1], al
  110. ; filling the hours buffer
  111. ; r8 will contain our digits counter : max is 8
  112. mov r8, 8
  113. pop rax
  114. print_time_hours_loop:
  115. mov rcx, 10
  116. xor rdx, rdx
  117. div rcx
  118. add dl, 0x30
  119. cmp rax, 0
  120. jne print_time_hours_print_mod
  121. cmp rdx, 0
  122. je print_time_hours_loop_end
  123. print_time_hours_print_mod:
  124. mov r9, hours
  125. 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. ; print hours + timestr
  134. add r8, 1
  135. cmp r8, 7
  136. jle print_time_hours_cont
  137. mov r8, 7
  138. print_time_hours_cont:
  139. mov r9, hours
  140. add r9, r8
  141. mov rcx, 9
  142. sub rcx, r8
  143. add rcx, timestrlen
  144. mov rax, 1 ; write
  145. mov rdi, 1 ; stdout
  146. mov rsi, r9
  147. mov rdx, rcx
  148. syscall
  149. ; Attempt to read from stdin
  150. ; if something read, enter has been pressed
  151. mov rax, 0
  152. mov rdi, 0
  153. mov rsi, buf
  154. mov rdx, 1
  155. syscall
  156. cmp rax, 0
  157. jge flush_stdin ; flush stdin and exit
  158. mov rax, 35 ; nanosleep
  159. mov rdi, ts_sleep
  160. mov rsi, 0
  161. syscall
  162. jmp print_time ; main loop
  163. flush_stdin:
  164. mov rax, 0
  165. mov rdi, 0
  166. mov rsi, buf
  167. mov rdx, 1
  168. syscall
  169. cmp rax, 0
  170. je newline
  171. jg flush_stdin
  172. exit:
  173. mov rax, 60 ; sys_exit
  174. mov rdi, 0 ; OK
  175. syscall
  176. fault:
  177. mov rax, 1 ; write
  178. mov rdi, 2 ; stderr
  179. mov rsi, nl
  180. mov rdx, 1
  181. syscall
  182. mov rax, 1
  183. mov rsi, faultmsg
  184. mov rdx, faultmsglen
  185. syscall
  186. mov rax, 60 ; sys_exit
  187. mov rdi, 1 ; failure
  188. syscall
  189. newline:
  190. mov rax, 1
  191. mov rdi, 1
  192. mov rsi, nl
  193. mov rdx, 1
  194. syscall
  195. jmp exit
  196. section .data
  197. ts_start:
  198. tv_start_s dq 0
  199. tv_start_us dq 0
  200. faultmsg: db "fault", 0xA
  201. faultmsglen: equ $ - faultmsg
  202. msg: db "0 Hello, world!", 10
  203. msglen: equ $ - msg
  204. hours: db "000000000"
  205. timestr: db ":00:00.0000 ", 0x0D
  206. timestrlen: equ $ - timestr
  207. nl: db 0x0A
  208. buf: db 0
  209. ts_cur:
  210. tv_cur_s dq 0
  211. tv_cur_us dq 0
  212. ts_sleep:
  213. tv_sleep_s dd 0,0
  214. tv_sleep_us dd 10000000,0
  215. ;; 1/2s sleep
  216. ;ts_sleep:
  217. ; tv_sleep_s dq 0
  218. ; tv_sleep_us dq 500000000
  219. .end: