Guest User

Untitled

a guest
Mar 26th, 2019
74
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. v;/****************************************************************************/;
  2. ;; Задание:
  3. ;; Програма вводит строку текста и выводит множество символов этой строки в
  4. ;; порядке убывания числа вхождений каждого символа в строку.
  5. ;; Выходное множество символов представляется в формате ""C1:N1,C2:N2,...",
  6. ;; где Ci - символ, а Ni - число вхождений этого символа, представленное в
  7. ;; десятичном виде. Если какие-либо слова строки могут быть интерпретированы
  8. ;; как беззнаковые пятиричные числа (размерность не более 2 байт), то цифры этих
  9. ;; чисел не попадают в процесс формирования выходного множества. Сумма всех
  10. ;; таких чисел выводится в двоичном виде.
  11. ;/****************************************************************************/;
  12. ;сегмент данных
  13. datas segment
  14. maxlength_in db 79 ;начало буфера для входной строки
  15. length_in db 0 ;реально введеннное количество символов
  16. string_in db 80 dup('0')
  17.  
  18. length db 0 ;длина строки, не содержащей пятиричных чисел
  19. string db 79 dup ('0') ;сама строка
  20.  
  21. length2 db 0 ;длина массива символов
  22. symbols db 158 dup ('$') ;массив символов в виде [ASCII код символа][частота]
  23.  
  24. sum dw 0 ;сумма всех пятиричных чисел
  25. max_frequency db 0 ;максимальная частота
  26. digitFh db 05h
  27. fiveexp dw 1 ;Табличка для перевода из основания 5
  28. dw 5 ;в основание 10
  29. dw 25
  30. dw 125
  31. dw 625
  32. dw 3125
  33. dw 15625
  34. numFlag db 0
  35. wordLength db 0
  36. numberLength db 0
  37.  
  38. message01 db 10,13,'Введите строку:',10,13,'->$'
  39. message02 db 0,' : ',30h,30h,30h,10,13,'$'
  40. message03 db 10,13,'Вхождение символов:',10,13,'$'
  41. datas ends
  42.  
  43. ;сегмент стека
  44. stacks segment
  45. db 100h dup(?)
  46. stacks ends
  47.  
  48. ;сегмент кода
  49. codes segment
  50. assume ss:stacks, ds:datas, cs:codes
  51.  
  52. ;/****************************************************************************/;
  53. ; Ввод строки и определение ее длины
  54. ;/****************************************************************************/;
  55. enter_string proc
  56. mov ah,0Ah
  57. lea dx,maxlength_in
  58. int 21h
  59. ret
  60. enter_string endp
  61.  
  62. ;/****************************************************************************/;
  63. ; подсчет частоты каждого символа
  64. ;/****************************************************************************/;
  65. calculate_symbols proc
  66. LOCALS
  67. cmp length,0 ;Длина стороки без чисел = 0
  68. jz @@end
  69.  
  70. xor bx,bx
  71. mov bl,length ;bх = length
  72. xor di,di ;di для строки symbols
  73. mov si,-1
  74. mov dl,20h ;в dl код пробела
  75. mov dh,0
  76. @@scan_beg:
  77. inc si ;идем по циклу в поисках нового символа
  78. cmp si,bx ;Надеюсь ещё не конец строки
  79. jge @@scan_end ;А ТО КАК....
  80. mov al,string[si] ;al = string[si]
  81. cmp al,dl ;al = пробел?
  82. jz @@scan_beg ;Если ,то следю символ, а так - дальше
  83.  
  84. push si ;подсчет кол-ва символов
  85. mov ah,1 ;Ага, первое вхождение уже есть!!!
  86. @@calc_freq_beg:
  87. inc si
  88. cmp si,bx
  89. jge @@calc_freq_end ;Искать до конца строки!!!
  90. cmp string[si],al ;Неужли снова он?
  91. jne @@calc_freq_beg ;Не, показалось!!!
  92. inc ah ; Или всё-таки ОН?!?!
  93. mov string[si],dl ;заменяем новый, подсчитанный символ на пробел
  94. jmp short @@calc_freq_beg ;Что бы не видеть его снова, походу!!!
  95. ;Или нам так больше нравится?!?!
  96. @@calc_freq_end:
  97. cmp ah,max_frequency ;определяем максимальную частоту среди символов
  98. jle @@not_greater
  99. mov max_frequency,ah ;и заносим её из ah
  100. @@not_greater:
  101. mov word ptr symbols[di],ax ;записываем в массив symbols код символа
  102. ;и его частоту
  103. add di,2 ;в di 2,т.к. у нас там и символ и его вхождение
  104. pop si ;Так или иначе, а начнём мы все равно
  105. ;с символа, следующего за предыдущим!!!
  106.  
  107. jmp short @@scan_beg
  108. @@scan_end:
  109.  
  110. mov dx,di ;длина массива symbols
  111. mov length2,dl
  112. @@end:
  113. ret
  114. calculate_symbols endp
  115.  
  116.  
  117. ;/****************************************************************************/;
  118. ; вывод "символ : частота "
  119. ;/****************************************************************************/;
  120. print_symbols proc
  121. LOCALS
  122. cmp length,0 ;В строке с символами кто нибудь наблюдается???
  123. jz @@for1end ;@@for1end - зашифрованная метка конца процедуры!
  124.  
  125. xor di,di
  126. mov bx,0A64h ;в bh - 10, в bl - 100
  127. xor cx,cx
  128. mov cl,length2 ;В сх длину строки symbols
  129.  
  130. @@for1beg:
  131. cmp max_frequency,0h ;Если получилось так, что символов с нулевым
  132. ;вхождением отсутствует, тогда
  133. jz @@for1end ;конец!!!
  134.  
  135. xor si,si ;Счётчик, с помощью колторого просматриваем строку.
  136. @@for2beg:
  137. cmp si,cx ;Ба, конец!!! Надо уменьшить max_frequency
  138. jge @@for2end
  139. mov ax,word ptr symbols[si] ;ах = очередному символу.
  140. cmp ah,max_frequency ;частота символа меньше максимальной - не выводим
  141. jnz @@not_equal_max
  142. ;ZYRAB
  143. mov message02[0],al ;вывод символа symbols[si]
  144. inc si
  145.  
  146. mov al,ah ;делим на 100 - выделяем цифру сотен
  147. xor ah,ah
  148. div bl
  149. add message02[4],al
  150.  
  151. mov al,ah ;делим на 10 - выделяем цифры десятков и единиц
  152. xor ah,ah
  153. div bh
  154. add message02[5],al
  155. add message02[6],ah
  156.  
  157. mov ah,09h
  158. lea dx,message02
  159. int 21h
  160.  
  161. mov message02[4],30h
  162. mov message02[5],30h
  163. mov message02[6],30h ;начиная от ZYRAB, сначала выводится символ
  164. ;а затем, количество вхождений.
  165.  
  166. inc si
  167. jmp short @@for2beg
  168. @@not_equal_max:
  169. add si,2
  170. jmp short @@for2beg
  171. @@for2end: ;А здесь как раз и творится беспредел с
  172. dec max_frequency ;уменьшением числа вхождений
  173. jmp @@for1beg ;Будем искать символ с меньшим вхождением!!!Go!!!
  174. @@for1end:
  175.  
  176. ret
  177. print_symbols endp
  178.  
  179.  
  180. ;/****************************************************************************/;
  181. ; поиск пятиричных чисел и вывод их суммы
  182. ;/****************************************************************************/;
  183. find_pental_numbers proc
  184. LOCALS
  185. cmp length_in,0 ;Вы забыли ввести символы???
  186. jnz @@ok
  187. jmp @@binary_sum_end
  188. @@ok:
  189. mov si,-1 ;si счётчик.
  190. xor di,di ;Очень важный момент!!!
  191. xor bh,bh ;в bx - length_in
  192. mov bl,length_in
  193.  
  194. @@calc_sum_beg:
  195. inc si
  196. cmp si,bx ;если не конец строки
  197. jl @@ok1 ;то дальше
  198. jmp @@calc_sum_end ;Единственный выход из этой процедуры
  199. @@ok1:
  200. cmp string_in[si],20h ;если пробел - переходим к следующему символу
  201. jz @@calc_sum_beg
  202.  
  203. ;ПОДСЧЁТ ДЛИНЫ ОЧЕРЕДНОГО СЛОВА
  204. push si ;si в стек
  205. mov wordLength,1 ;В wordLength длина слова
  206. inc si
  207. @@calc_length_beg:
  208. cmp si,bx ;если конец строки,
  209. jge @@calc_length_end
  210. cmp string_in[si],20h ;ИЛИ ПРОБЕЛ
  211. jz @@calc_length_end ;то закончим с определением wordLength
  212. inc wordLength
  213. inc si
  214. jmp short @@calc_length_beg
  215. @@calc_length_end:
  216. pop si ;si из стека
  217.  
  218. cmp wordLength,7 ;максимальное пятиричное число - 4044120(5)=65535(10)
  219. jg @@copy_word_beg
  220.  
  221. push si ;ПРОВЕРКА НА 5тиричные цифры
  222. mov cl,wordLength ;В cl длину слова
  223. mov numberLength,0 ;Длина числа = 0
  224. @@check_word_beg:
  225. xor ax,ax
  226. cmp si,bx
  227. jge @@check_word_end ;Лишь бы не конец строки
  228. cmp string_in[si],30h ;Если <'0'
  229. jl @@check_word_end
  230. cmp string_in[si],34h ;или >'4'
  231. jg @@check_word_end ;то это не число!!!
  232. inc numberLength
  233. inc si
  234. inc ax ;Это логика!!! (true or false)
  235. dec cl
  236. cmp cl,0
  237. jg @@check_word_beg
  238. @@check_word_end:
  239. pop si
  240.  
  241. cmp ax,0 ;Прочитанное слово не число!!!
  242. jz @@copy_word_beg
  243.  
  244. xor dh,dh ;преобразование в число
  245. mov dl,numberLength ;В dx - количество цифр в числе
  246. push dx
  247. xor cx,cx
  248. push si
  249. push di
  250. xor di,di
  251. add si,dx ;si указывает на конец числа.
  252. dec si
  253. @@convert_beg:
  254. xor ax,ax
  255. mov al, byte ptr string_in[si] ;Преобразование с конца
  256. sub al,30h
  257. mul fiveexp[di] ;Помните табличку для перевода из
  258. ;основания 5 в основание 10
  259. add cx,ax ;В сх - десятичное представление числа
  260. add di,2
  261. dec si ;Мы ещё ближе к началу числа
  262. dec numberLength
  263. cmp numberLength,0 ;От числа ещё что-то осталось
  264. jg @@convert_beg
  265. @@convert_end:
  266. pop di
  267. pop si
  268. pop dx
  269. add si,dx
  270. add sum,cx ;Скаладываем с тем что есть
  271. jmp @@calc_sum_beg
  272.  
  273. @@copy_word_beg: ;копируем слово в строку символов
  274. cmp wordLength,0
  275. jnz @@ok2
  276. jmp @@calc_sum_beg ;Перепрыгнуть туда, где определ-ся
  277. ;Длина слова, числа и т.п.
  278. @@ok2:
  279. mov al,string_in[si] ;В аl - очередной символ
  280. mov string[di],al ;Засунем мы его в строку без чисел!!!
  281. inc di
  282. inc si
  283. dec wordLength
  284. jmp short @@copy_word_beg
  285.  
  286. @@calc_sum_end:
  287. mov bx,di
  288. mov length,bl ;В байте bl - длина строки без чисел
  289. ;Помещаем это чило в length
  290.  
  291. mov bx,sum ;Почти стандартный вывод суммы
  292. mov cx,16 ;в двоичном виде даже ничего интересного нет!!!
  293. mov ah,2h
  294. @@binary_sum_end:
  295. ret
  296. find_pental_numbers endp
  297.  
  298.  
  299. ;/****************************************************************************/;
  300. ; точка входа
  301. ;/****************************************************************************/;
  302. main:
  303. mov ax,datas
  304. mov ds,ax
  305.  
  306. mov ah,9h ;вывод приглашения
  307. lea dx,message01
  308. int 21h
  309.  
  310. call enter_string ;ввод строки
  311.  
  312. call find_pental_numbers ;поиск пятиричных чисел и вывод их суммы
  313.  
  314. mov ah,9h
  315. lea dx,message03
  316. int 21h
  317.  
  318. call calculate_symbols ;подсчет частоты символов
  319. call print_symbols ;вывод данных
  320.  
  321. mov ah,4Ch
  322. int 21h
  323. codes ends
  324. end main
RAW Paste Data