fork download
  1. section .text
  2.  
  3. global _start
  4.  
  5. _start:
  6. mov eax,s ;куда вводить
  7. mov ecx,32 ;макс длина строки
  8. call instr ;ввод строки
  9. mov esi,s ;введенная строка
  10. mov ebx,0 ;кол-во найденных полных квадратов=0
  11. lp1:
  12. ;поиск начала очередного числа
  13. mov al,[esi] ;прочитать очередной символ
  14. cmp al,0 ;если конец строки
  15. jz fin1 ;то закончить
  16. cmp al,' ' ;если не пробел
  17. jnz m1 ;то переход
  18. inc esi ;следующий символ
  19. jmp lp1 ;продолжить поиск начала числа
  20. m1:;нашли очередное число в введенной строке
  21. mov edi,0 ;сумма=0
  22. mov eax,0 ;обнулить eax
  23. lp2:;поиск конца числа
  24. mov al,[esi] ;прочитать очердной символ
  25. cmp al,0 ;если конец строки
  26. jz m2 ;то закончить обработку числа
  27. cmp al,' ' ;если пробел
  28. jz m2 ;то закончить обработку числа
  29. cmp al,'9' ;если это не цифра,
  30. jnbe m5 ;то пропускаем
  31. cmp al,'0' ;если это не цифра,
  32. jb m5 ;то пропускаем
  33. sub al,'0' ;получаем цифровое значение
  34. shl edi,1 ;умножаем сумму на 10
  35. add eax, edi
  36. shl edi, 2
  37. add edi, eax ;прибавляем текущее значение
  38. m5: inc esi ;следующий символ
  39. jmp lp2 ;продолжить поиск конца числа
  40. m2: ;в edi находится значение очередного числа
  41. mov ecx,0 ;значение предполагаемого корня=0
  42. lp3:
  43. mov eax,ecx ;значение предполагаемого корня
  44. mul eax ;возводим в квадрат
  45. cmp eax,edi ;сравниваем с значением очередного числа
  46. ja lp1 ;если квадрат больше, то это число точно не полный квадрат, перейти
  47.  
  48. jnz m3 ;если не равны, то пробовать следующий предполагаемый корень
  49. inc ebx ;если равны, увеличить кол-во найденных полных квадратов
  50. jmp lp1 ;поиск следующего числа в строке
  51. m3: inc ecx ;пробовать следующий предполагаемый корень
  52. jmp lp3 ;продолжить проверку на полный квадрат
  53. fin1: mov eax,ebx ;кол-во найденных полных квадратов
  54. call printdec ;вывести его на консоль
  55.  
  56. mov eax, 1 ;ф-я завершения
  57. xor ebx, ebx ; errno
  58. int 0x80 ;выход
  59.  
  60. ;вывод числа на консоль
  61. ;eax - число
  62. printdec:
  63. push ecx ;сохраняем регистры
  64. push edx
  65. push ebx
  66. push esi
  67. push edi
  68. mov edi,buf ;куда преобразовывать в строку
  69. mov ebx,10 ;основание системы
  70. xor ecx,ecx ;в eсх будет количество цифр в десятичном числе
  71. @@m1a: xor edx,edx
  72. div ebx ;делим число на степени 10
  73. push edx ;и сохраняем остаток от деления(коэффициенты при степенях) в стек
  74. inc ecx ;увеличиваем количество десятичных цифр числа
  75. test eax,eax ;после делия остался 0?
  76. jnz @@m1a ;если нет, продолжаем
  77. @@m2a: pop eax ;взять из стека цифру цисла
  78. add al,'0' ;преобразовываем цифру в ASCII символ
  79. stosb ;сохраняем в буфер
  80. loop @@m2a ;все цифры
  81. mov al,0
  82. stosb ;добавить признак завершения строки
  83. mov eax,buf ;строка с результатом
  84. call outstr ;вывод числа, преобразованного в строку
  85. pop edi
  86. pop esi
  87. pop ebx ;восстанавливаем регистры
  88. pop edx
  89. pop ecx
  90. ret ;выход из подпрограммы
  91.  
  92. ;вывод строки на экран
  93. ;eax - адрес ascii строки
  94. outstr: push eax ;сохранить регистры
  95. push ebx
  96. push ecx
  97. push edx
  98. mov ecx,eax ;запомнить адрес строки
  99. xor edx,edx ;кол-во символов в строке
  100. strlp: cmp byte [eax], 0 ;если текущий символ 0
  101. jz strex ;то закончить подсчет
  102. inc eax ;следующий символ
  103. inc edx ;увеличить кол-во символов в строке
  104. jmp strlp ;подсчитать все символы
  105. strex: mov eax,4 ;sys_write
  106. mov ebx,1 ;stdout
  107. int 0x80 ;вывести
  108. pop edx ;восстановить регистры
  109. pop ecx
  110. pop ebx
  111. pop eax
  112. ret
  113.  
  114. ;ввод строки с клавиатуры
  115. ;eax - адрес ascii строки
  116. ;ecx - максимальная длина строки
  117. ;Возвращает
  118. ;eax - реальная длина строки
  119. instr: push ebx ;сохранить регистры
  120. push ecx
  121. push edx
  122. lea edx,[ecx+1]
  123. mov ecx,eax ;запомнить адрес строки
  124. mov eax,3 ;sys_read
  125. mov ebx,0 ;stdin
  126. int 0x80 ;ввести
  127. mov byte [ecx+eax],0
  128. pop edx ;восстановить регистры
  129. pop ecx
  130. pop ebx
  131. ret
  132.  
  133. section .data
  134.  
  135. segment .bss
  136.  
  137. s resb 128 ;вводимая строка
  138. buf resb 32 ;буфер для выводимой строки-числа
Success #stdin #stdout 0s 5268KB
stdin
4 55 81 32 49
stdout
3