fork download
  1. section .data
  2. ; Определяем числа как строки (десятичные)
  3. num1 db '12345', 0 ; Первое число (можно изменить)
  4. num2 db '67890', 0 ; Второе число (можно изменить)
  5. result times 20 db 0 ; Буфер для результата
  6. N equ 5 ; Размер чисел в байтах (можно изменить)
  7.  
  8. ; Сообщения
  9. msg1 db 'First number: ', 0
  10. msg2 db 'Second number: ', 0
  11. msg3 db 'Sum: ', 0
  12. newline db 13, 10, 0
  13.  
  14. section .bss
  15. ; Дополнительные переменные при необходимости
  16.  
  17. section .text
  18. global _start
  19.  
  20. _start:
  21. ; Вывод первого числа
  22. mov eax, 4 ; sys_write
  23. mov ebx, 1 ; stdout
  24. mov ecx, msg1
  25. mov edx, 13 ; длина msg1
  26. int 0x80
  27.  
  28. mov eax, 4
  29. mov ebx, 1
  30. mov ecx, num1
  31. mov edx, N
  32. int 0x80
  33.  
  34. mov eax, 4
  35. mov ebx, 1
  36. mov ecx, newline
  37. mov edx, 2
  38. int 0x80
  39.  
  40. ; Вывод второго числа
  41. mov eax, 4
  42. mov ebx, 1
  43. mov ecx, msg2
  44. mov edx, 15 ; длина msg2
  45. int 0x80
  46.  
  47. mov eax, 4
  48. mov ebx, 1
  49. mov ecx, num2
  50. mov edx, N
  51. int 0x80
  52.  
  53. mov eax, 4
  54. mov ebx, 1
  55. mov ecx, newline
  56. mov edx, 2
  57. int 0x80
  58.  
  59. ; Сложение двух N-байтовых десятичных чисел
  60. call add_decimal_numbers
  61.  
  62. ; Вывод результата
  63. mov eax, 4
  64. mov ebx, 1
  65. mov ecx, msg3
  66. mov edx, 5 ; длина msg3
  67. int 0x80
  68.  
  69. mov eax, 4
  70. mov ebx, 1
  71. mov ecx, result
  72. ; Нужно вычислить длину результата
  73. mov edi, result
  74. call strlen
  75. mov edx, eax ; длина результата в edx
  76. int 0x80
  77.  
  78. mov eax, 4
  79. mov ebx, 1
  80. mov ecx, newline
  81. mov edx, 2
  82. int 0x80
  83.  
  84. ; Завершение программы
  85. mov eax, 1 ; sys_exit
  86. xor ebx, ebx ; код возврата 0
  87. int 0x80
  88.  
  89. ; Процедура сложения двух десятичных чисел
  90. ; Вход: num1, num2 - строки с десятичными числами
  91. ; Выход: result - строка с результатом
  92. add_decimal_numbers:
  93. pusha
  94.  
  95. ; Подготовка
  96. mov ecx, N
  97. mov esi, num1
  98. mov edi, num2
  99. mov ebx, result
  100.  
  101. ; Проверяем знаки чисел
  102. mov al, [esi]
  103. mov bl, [edi]
  104.  
  105. ; Флаг знака результата (0 - положительный, 1 - отрицательный)
  106. mov dh, 0
  107.  
  108. ; Если оба числа положительные
  109. cmp al, '-'
  110. je check_second_sign
  111. cmp bl, '-'
  112. je check_second_sign
  113.  
  114. ; Оба положительные
  115. jmp prepare_addition
  116.  
  117. check_second_sign:
  118. cmp al, '-'
  119. jne first_positive_second_negative
  120. cmp bl, '-'
  121. jne first_negative_second_positive
  122.  
  123. ; Оба отрицательные
  124. mov dh, 1 ; Результат будет отрицательным
  125. inc esi ; Пропускаем знак '-'
  126. inc edi
  127. dec ecx ; Уменьшаем счетчик
  128. jmp prepare_addition
  129.  
  130. first_positive_second_negative:
  131. ; Первое положительное, второе отрицательное
  132. inc edi ; Пропускаем знак у второго числа
  133. call subtract_numbers
  134. jmp process_result_sign
  135.  
  136. first_negative_second_positive:
  137. ; Первое отрицательное, второе положительное
  138. inc esi ; Пропускаем знак у первого числа
  139. xchg esi, edi ; Меняем местами, чтобы вычитать из второго
  140. call subtract_numbers
  141. jmp process_result_sign
  142.  
  143. prepare_addition:
  144. ; Подготовка к сложению
  145. mov esi, num1
  146. mov edi, num2
  147. mov ebx, result
  148.  
  149. ; Если были знаки, пропускаем их
  150. cmp byte [esi], '-'
  151. jne check_num2_sign
  152. inc esi
  153. check_num2_sign:
  154. cmp byte [edi], '-'
  155. jne start_addition
  156. inc edi
  157.  
  158. start_addition:
  159. ; Начинаем сложение с младших разрядов
  160. mov ecx, N
  161. add esi, ecx
  162. dec esi ; Указываем на последний символ
  163. add edi, ecx
  164. dec edi
  165. add ebx, ecx
  166. dec ebx
  167.  
  168. mov byte [ebx+1], 0 ; Конец строки
  169. mov byte [ebx], 0 ; Инициализируем последний байт
  170.  
  171. clc ; Сброс флага переноса
  172.  
  173. addition_loop:
  174. mov al, [esi]
  175. sub al, '0' ; Преобразуем ASCII в число
  176.  
  177. mov ah, [edi]
  178. sub ah, '0' ; Преобразуем ASCII в число
  179.  
  180. ; Сложение с учетом предыдущего переноса
  181. adc al, ah
  182.  
  183. ; Проверка на переполнение (если сумма >= 10)
  184. cmp al, 10
  185. jb no_carry
  186.  
  187. sub al, 10
  188. stc ; Устанавливаем флаг переноса
  189. jmp store_digit
  190.  
  191. no_carry:
  192. clc ; Сброс флага переноса
  193.  
  194. store_digit:
  195. add al, '0' ; Преобразуем число в ASCII
  196. mov [ebx], al
  197.  
  198. ; Переход к следующему разряду
  199. dec esi
  200. dec edi
  201. dec ebx
  202.  
  203. loop addition_loop
  204.  
  205. ; Если остался перенос
  206. jnc addition_done
  207.  
  208. ; Добавляем старший разряд
  209. mov byte [ebx], '1'
  210. jmp addition_complete
  211.  
  212. addition_done:
  213. mov byte [ebx], '0'
  214.  
  215. addition_complete:
  216. ; Если результат отрицательный, добавляем знак '-'
  217. cmp dh, 1
  218. jne process_result_sign
  219.  
  220. dec ebx
  221. mov byte [ebx], '-'
  222.  
  223. process_result_sign:
  224. ; Копируем результат в начало буфера
  225. mov esi, result
  226. mov edi, result
  227.  
  228. ; Пропускаем начальные нули
  229. skip_zeros:
  230. cmp byte [esi], '0'
  231. jne copy_result
  232. inc esi
  233. jmp skip_zeros
  234.  
  235. copy_result:
  236. ; Копируем остаток
  237. mov al, [esi]
  238. mov [edi], al
  239. inc esi
  240. inc edi
  241. test al, al
  242. jnz copy_result
  243.  
  244. ; Если все было нулями
  245. mov esi, result
  246. cmp byte [esi], 0
  247. jne not_all_zeros
  248. mov byte [esi], '0'
  249. mov byte [esi+1], 0
  250.  
  251. not_all_zeros:
  252. popa
  253. ret
  254.  
  255. ; Процедура вычитания (упрощенная версия)
  256. ; Вход: ESI - уменьшаемое, EDI - вычитаемое
  257. subtract_numbers:
  258. pusha
  259. ; Здесь должна быть реализация вычитания
  260. ; Для простоты возвращаем "0"
  261. mov edi, result
  262. mov byte [edi], '0'
  263. mov byte [edi+1], 0
  264. popa
  265. ret
  266.  
  267. ; Функция вычисления длины строки
  268. ; Вход: EDI - указатель на строку
  269. ; Выход: EAX - длина строки
  270. strlen:
  271. push ecx
  272. push edi
  273. xor ecx, ecx
  274. not ecx
  275. xor al, al
  276. cld
  277. repne scasb
  278. not ecx
  279. dec ecx
  280. mov eax, ecx
  281. pop edi
  282. pop ecx
  283. ret
Success #stdin #stdout 0s 5312KB
stdin
Standard input is empty
stdout
First number:12345
Second number: 67890
Sum: