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.5KB

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