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. ; Вычисляем длину результата
  70. mov edi, result
  71. call strlen
  72. mov edx, eax ; длина результата в edx
  73.  
  74. mov eax, 4
  75. mov ebx, 1
  76. mov ecx, result
  77. int 0x80
  78.  
  79. mov eax, 4
  80. mov ebx, 1
  81. mov ecx, newline
  82. mov edx, 2
  83. int 0x80
  84.  
  85. ; Завершение программы
  86. mov eax, 1 ; sys_exit
  87. xor ebx, ebx ; код возврата 0
  88. int 0x80
  89.  
  90. ; Процедура сложения двух десятичных чисел
  91. ; Вход: num1, num2 - строки с десятичными числами
  92. ; Выход: result - строка с результатом
  93. add_decimal_numbers:
  94. pusha
  95.  
  96. ; Инициализация
  97. mov ecx, N ; Длина чисел
  98. mov esi, num1
  99. mov edi, num2
  100. mov ebx, result
  101.  
  102. ; Подготовка указателей на последние символы
  103. add esi, ecx
  104. dec esi ; ESI указывает на последний символ num1
  105. add edi, ecx
  106. dec edi ; EDI указывает на последний символ num2
  107. add ebx, ecx
  108. dec ebx ; EBX указывает на последнюю позицию в result
  109.  
  110. ; Завершающий нуль для результата
  111. mov byte [ebx+1], 0
  112.  
  113. ; Сброс флага переноса
  114. clc
  115. mov dh, 0 ; Флаг переноса для следующего разряда
  116.  
  117. addition_loop:
  118. ; Преобразуем символы в числа
  119. mov al, [esi]
  120. sub al, '0'
  121.  
  122. mov ah, [edi]
  123. sub ah, '0'
  124.  
  125. ; Сложение с учетом переноса
  126. adc al, ah
  127.  
  128. ; Проверяем, нужно ли установить перенос для следующего разряда
  129. mov dh, 0 ; Сбрасываем флаг переноса
  130. cmp al, 10
  131. jb no_carry
  132. sub al, 10
  133. mov dh, 1 ; Устанавливаем флаг переноса
  134.  
  135. no_carry:
  136. ; Преобразуем число обратно в символ
  137. add al, '0'
  138. mov [ebx], al
  139.  
  140. ; Двигаем указатели
  141. dec esi
  142. dec edi
  143. dec ebx
  144.  
  145. ; Подготавливаем перенос для следующей итерации
  146. cmp dh, 1
  147. jne no_carry_set
  148. stc ; Устанавливаем флаг переноса
  149. jmp continue_loop
  150. no_carry_set:
  151. clc ; Сбрасываем флаг переноса
  152.  
  153. continue_loop:
  154. dec ecx
  155. jnz addition_loop
  156.  
  157. ; Проверяем остался ли перенос после последнего разряда
  158. jnc addition_done
  159.  
  160. ; Добавляем '1' в начало если есть перенос
  161. mov byte [ebx], '1'
  162. jmp format_result
  163.  
  164. addition_done:
  165. mov byte [ebx], '0'
  166.  
  167. format_result:
  168. ; Находим начало результата
  169. mov ecx, N
  170. lea ebx, [result+ecx]
  171. mov byte [ebx], 0 ; Завершающий нуль
  172.  
  173. ; Пропускаем ведущие нули
  174. mov esi, result
  175. skip_leading_zeros:
  176. cmp byte [esi], '0'
  177. jne check_if_all_zeros
  178. inc esi
  179. jmp skip_leading_zeros
  180.  
  181. check_if_all_zeros:
  182. ; Если все символы были '0'
  183. cmp byte [esi], 0
  184. jne copy_formatted
  185. dec esi ; Возвращаем одну '0'
  186.  
  187. copy_formatted:
  188. ; Копируем форматированный результат в начало буфера
  189. mov edi, result
  190. copy_loop:
  191. mov al, [esi]
  192. mov [edi], al
  193. inc esi
  194. inc edi
  195. test al, al
  196. jnz copy_loop
  197.  
  198. popa
  199. ret
  200.  
  201. ; Функция вычисления длины строки
  202. ; Вход: EDI - указатель на строку
  203. ; Выход: EAX - длина строки
  204. strlen:
  205. push ecx
  206. push edi
  207. xor ecx, ecx
  208. not ecx
  209. xor al, al
  210. cld
  211. repne scasb
  212. not ecx
  213. dec ecx
  214. mov eax, ecx
  215. pop edi
  216. pop ecx
  217. ret
Success #stdin #stdout 0s 5332KB
stdin
Standard input is empty
stdout
First number:12345
Second number: 67890
Sum: 79135