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 3.1KB

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