fork download
  1. section .data
  2. ; Текстовые сообщения
  3. msg_prompt db 'Введите число (или 0 для выхода): ', 0
  4. msg_result db 'Результат: ', 0
  5. msg_continue db 'Продолжить? (1-да, 0-нет): ', 0
  6. msg_exit db 'Выход из калькулятора', 10, 0
  7. msg_error db 'Ошибка ввода!', 10, 0
  8. newline db 10, 0
  9.  
  10. ; Буфер для ввода
  11. buffer times 16 db 0
  12.  
  13. section .bss
  14. ; Переменные
  15. num1 resq 1 ; 64-битное число
  16. num2 resq 1
  17. result resq 1
  18. choice resb 1
  19.  
  20. section .text
  21. global _start
  22.  
  23. _start:
  24. ; Основной цикл калькулятора
  25. main_loop:
  26. ; Выводим приглашение
  27. mov rax, 1 ; sys_write (64-bit)
  28. mov rdi, 1 ; stdout
  29. mov rsi, msg_prompt
  30. mov rdx, 31 ; длина строки
  31. syscall
  32.  
  33. ; Читаем первое число
  34. call read_number
  35. cmp rax, 0 ; Если ввели 0
  36. je exit_program ; выходим
  37.  
  38. mov [num1], rax ; Сохраняем первое число
  39.  
  40. ; Выводим приглашение для второго числа
  41. mov rax, 1
  42. mov rdi, 1
  43. mov rsi, msg_prompt
  44. mov rdx, 31
  45. syscall
  46.  
  47. ; Читаем второе число
  48. call read_number
  49. mov [num2], rax
  50.  
  51. ; СЛОЖЕНИЕ
  52. mov rax, [num1]
  53. add rax, [num2] ; Складываем
  54. mov [result], rax ; Сохраняем результат
  55.  
  56. ; Выводим "Результат: "
  57. mov rax, 1
  58. mov rdi, 1
  59. mov rsi, msg_result
  60. mov rdx, 11
  61. syscall
  62.  
  63. ; Преобразуем число в строку и выводим
  64. mov rax, [result]
  65. call print_number
  66.  
  67. ; Новая строка
  68. mov rax, 1
  69. mov rdi, 1
  70. mov rsi, newline
  71. mov rdx, 1
  72. syscall
  73.  
  74. ; Спрашиваем, продолжить ли
  75. mov rax, 1
  76. mov rdi, 1
  77. mov rsi, msg_continue
  78. mov rdx, 31
  79. syscall
  80.  
  81. ; Читаем выбор
  82. mov rax, 0 ; sys_read
  83. mov rdi, 0 ; stdin
  84. mov rsi, choice
  85. mov rdx, 2
  86. syscall
  87.  
  88. ; Проверяем выбор
  89. mov al, [choice]
  90. cmp al, '1'
  91. je main_loop ; Продолжаем если '1'
  92.  
  93. ; Иначе выходим
  94. jmp exit_program
  95.  
  96. ; Функция чтения числа
  97. read_number:
  98. push rbx
  99. push rcx
  100. push rdx
  101.  
  102. ; Читаем строку
  103. mov rax, 0 ; sys_read
  104. mov rdi, 0 ; stdin
  105. mov rsi, buffer
  106. mov rdx, 16
  107. syscall
  108.  
  109. ; Преобразуем строку в число
  110. xor rax, rax ; Обнуляем rax (результат)
  111. xor rbx, rbx ; Обнуляем rbx (текущий символ)
  112. mov rcx, buffer ; Указатель на строку
  113.  
  114. convert_loop:
  115. mov bl, [rcx] ; Берём символ
  116. cmp bl, 10 ; Проверяем конец строки
  117. je convert_done
  118. cmp bl, 0 ; Или нуль-терминатор
  119. je convert_done
  120.  
  121. ; Проверяем что это цифра
  122. cmp bl, '0'
  123. jl input_error
  124. cmp bl, '9'
  125. jg input_error
  126.  
  127. ; Преобразуем символ в цифру
  128. sub bl, '0'
  129.  
  130. ; Умножаем текущий результат на 10
  131. imul rax, 10
  132. add rax, rbx ; Добавляем новую цифру
  133.  
  134. inc rcx ; Следующий символ
  135. jmp convert_loop
  136.  
  137. convert_done:
  138. pop rdx
  139. pop rcx
  140. pop rbx
  141. ret
  142.  
  143. input_error:
  144. ; Выводим сообщение об ошибке
  145. mov rax, 1
  146. mov rdi, 1
  147. mov rsi, msg_error
  148. mov rdx, 14
  149. syscall
  150.  
  151. ; Возвращаем 0
  152. xor rax, rax
  153. jmp convert_done
  154.  
  155. ; Функция печати числа
  156. print_number:
  157. push rax
  158. push rbx
  159. push rcx
  160. push rdx
  161.  
  162. ; Преобразуем число в строку
  163. mov rbx, buffer + 15 ; Конец буфера
  164. mov byte [rbx], 0 ; Нуль-терминатор
  165. dec rbx
  166. mov byte [rbx], 10 ; Перенос строки
  167. dec rbx
  168.  
  169. mov rcx, 10 ; Делитель
  170.  
  171. ; Если число 0
  172. cmp rax, 0
  173. jne convert_loop2
  174. mov byte [rbx], '0'
  175. dec rbx
  176.  
  177. convert_loop2:
  178. xor rdx, rdx ; Обнуляем rdx для деления
  179. div rcx ; Делим rax на 10, остаток в rdx
  180.  
  181. ; Преобразуем остаток в символ
  182. add dl, '0'
  183. mov [rbx], dl
  184. dec rbx
  185.  
  186. ; Проверяем, закончили ли
  187. test rax, rax
  188. jnz convert_loop2
  189.  
  190. ; Выводим строку
  191. inc rbx ; Корректируем указатель
  192. mov rcx, rbx
  193. mov rdx, buffer + 16
  194. sub rdx, rcx ; Вычисляем длину
  195.  
  196. ; Теперь нужно правильно передать параметры
  197. mov rax, 1 ; sys_write
  198. mov rdi, 1 ; stdout
  199. mov rsi, rbx ; строка
  200. ; rdx уже содержит длину
  201. syscall
  202.  
  203. pop rdx
  204. pop rcx
  205. pop rbx
  206. pop rax
  207. ret
  208.  
  209. ; Выход из программы
  210. exit_program:
  211. ; Сообщение о выходе
  212. mov rax, 1
  213. mov rdi, 1
  214. mov rsi, msg_exit
  215. mov rdx, 20
  216. syscall
  217.  
  218. ; Завершаем программу
  219. mov rax, 60 ; sys_exit (64-bit)
  220. xor rdi, rdi ; код возврата 0
  221. syscall
Success #stdin #stdout 0s 5312KB
stdin
Standard input is empty
stdout
Введите число (илВыход из ка