fork(5) download
  1. global _start
  2.  
  3. section .data
  4. ten dq 10.0
  5. one dq 1.0
  6. zero dq 0.0
  7. negate dq 8000000000000000h
  8. result dd 0.0
  9. hex db '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
  10. length dd 0
  11. buffer db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  12.  
  13. section .text
  14.  
  15. _start:
  16. ;;
  17. ;; read the fp number from stdin
  18. ;;
  19. mov ecx, buffer
  20. mov edx, 32
  21. call read
  22. mov dword [length], eax
  23. movq xmm0, qword [zero]
  24. movq xmm1, qword [zero]
  25. movq xmm2, qword [ten]
  26. movq xmm4, qword [ten]
  27. ;;
  28. ;; loop through 1 character at a time
  29. ;;
  30. mov ebx, dword [length]
  31. test ebx, ebx
  32. jz quit ;; there's no input
  33. mov ecx, 0 ;; offset counter
  34. mov edx, 0 ;; 0 for before decimal, 1 for after decimal
  35. mov edi, 0 ;; 0 for positive, 1 for negative
  36. mov esi, buffer
  37. cmp byte [esi], '-'
  38. jne process
  39. mov edi, 1 ;; the number is negative
  40. inc ecx
  41. process:
  42. movzx eax, byte [esi + ecx]
  43. cmp al, '.' ;; does al contain a decimal point '.'
  44. jne next_check
  45. test edx, edx ;; more than 1 decimal error
  46. jnz quit
  47. mov edx, 1
  48. jmp continue_process
  49. next_check:
  50. sub eax, '0' ;; ascii digit to binary
  51. js end_process ;; not a digit since eax is negative
  52. cmp eax, 10
  53. jge end_process ;; not a digit since eax is >= 10
  54. test edx, edx ;; before or after decimal
  55. jnz mantissa_process
  56. mulsd xmm0, xmm2 ;; result characteristic * 10
  57. cvtsi2sd xmm3, eax
  58. addsd xmm0, xmm3 ;; result characteristic + next digit
  59. jmp continue_process
  60. mantissa_process:
  61. cvtsi2sd xmm3, eax
  62. divsd xmm3, xmm2 ;; next digit / current mantissa power of 10
  63. addsd xmm1, xmm3 ;; result mantissa + next fraction
  64. mulsd xmm2, xmm4 ;; mantissa power * 10
  65. continue_process:
  66. inc ecx
  67. cmp ecx, ebx
  68. jl process
  69. end_process:
  70. addsd xmm0, xmm1 ;; characteristic + mantissa
  71. test edi, edi ;; is the number supposed to be negative ?
  72. jz store_result
  73. movq xmm3, qword [negate]
  74. por xmm0, xmm3 ;; toggle the sign bit
  75. store_result:
  76. cvtsd2ss xmm0, xmm0 ;; double (64bit) to single (32) fp
  77. movd eax, xmm0
  78. mov dword[result], eax
  79. ;;
  80. ;; convert result to hex
  81. ;;
  82. to_hex:
  83. mov edi, buffer
  84. mov esi, hex
  85. mov ebx, 0
  86. mov eax, dword [result]
  87. mov bl, al
  88. and bl, 0fh
  89. mov bl, byte [esi + ebx]
  90. mov byte [edi + 7], bl
  91. shr eax, 4
  92. mov bl, al
  93. and bl, 0fh
  94. mov bl, byte [esi + ebx]
  95. mov byte [edi + 6], bl
  96. shr eax, 4
  97. mov bl, al
  98. and bl, 0fh
  99. mov bl, byte [esi + ebx]
  100. mov byte [edi + 5], bl
  101. shr eax, 4
  102. mov bl, al
  103. and bl, 0fh
  104. mov bl, byte [esi + ebx]
  105. mov byte [edi + 4], bl
  106. shr eax, 4
  107. mov bl, al
  108. and bl, 0fh
  109. mov bl, byte [esi + ebx]
  110. mov byte [edi + 3], bl
  111. shr eax, 4
  112. mov bl, al
  113. and bl, 0fh
  114. mov bl, byte [esi + ebx]
  115. mov byte [edi + 2], bl
  116. shr eax, 4
  117. mov bl, al
  118. and bl, 0fh
  119. mov bl, byte [esi + ebx]
  120. mov byte [edi + 1], bl
  121. shr eax, 4
  122. mov bl, al
  123. and bl, 0fh
  124. mov bl, byte [esi + ebx]
  125. mov byte [edi + 0], bl
  126. ;;
  127. ;; print result
  128. ;;
  129. print_dword:
  130. mov ecx, buffer
  131. mov edx, 8
  132. call write
  133. ;;
  134. ;; quit
  135. ;;
  136. quit:
  137. call exit
  138.  
  139. exit:
  140. mov eax, 01h ; exit()
  141. xor ebx, ebx ; errno
  142. int 80h
  143. read:
  144. mov eax, 03h ; read()
  145. mov ebx, 00h ; stdin
  146. int 80h
  147. ret
  148. write:
  149. mov eax, 04h ; write()
  150. mov ebx, 01h ; stdout
  151. int 80h
  152. ret
Success #stdin #stdout 0s 144KB
stdin
-1.5
stdout
bfc00000