Разбить заданную строку на две части - Assembler

Узнай цену своей работы

Формулировка задачи:

добрый день нужна программа, содержащая в себе подпрограмму, которая разбивает заданную строку на две части: первое слов (до первого пробела) и остальная часть строки (пробелы в начале строки убираются) после выполнения программы все слова выводятся в консоль по отдельности надыбал код не помню на каком сайте. проверил - работает. стал вникать в принципы ее реализации.. ии... всё )) ничего не понял может кто-то намекнуть на правильные ответы для возникших вопросов?)
Листинг программы
  1. .186 ;чтобы можно было использовать push <число>
  2. assume cs:code, ds:data, es:data
  3. SSEG segment stack ;сегмент стека
  4. db 400h dup (?)
  5. SSEG ends
  6. code segment para public 'code'
  7. start:
  8. mov ax, data
  9. mov ds, ax
  10. mov es, ax ;пусть es=ds=data
  11. lea dx, sString
  12. mov ah, 9
  13. int 21h ;ждем строку
  14. mov bMax, 80 ;задаем максимальное значение строки нулевом будет 80 - макс длина)
  15. lea dx, bMax первом после ввода останется фактич длина, а со второй идут данные
  16. mov ah, 0ah
  17. int 21h ;вводим строку
  18. lea dx, sResult
  19. mov ah, 9
  20. int 21h ;выводим заголовок о выводе слов
  21. mov wAddr, offset bString ;адрес строки
  22. next:
  23. push offset wAddr ;адрес адреса строки
  24. call FirstWord ;разбиваем на подстроки
  25. test ax, ax ;ax = адресу слова, =0 - одни пробелы
  26. jz finish конце пробелы - на выход
  27. mov dx, ax
  28. mov ah, 9
  29. int 21h ;выведем слово
  30. mov ah, 2 ;на новую строку
  31. mov dl, 0dh
  32. int 21h
  33. mov dl, 0ah
  34. int 21h
  35. cmp wAddr, 0 ;последнее слово?
  36. jne next ;продолжаем разбивать строку
  37. finish:
  38. lea dx, sPress
  39. mov ah, 9
  40. int 21h ;press any key
  41. mov ah, 8
  42. int 21h ;ждем any key
  43. mov ax, 4c00h
  44. int 21h ;bye
  45. ;Разбор строки на первое слово и все остальное
  46. ;Исходная строка портится! В конце слова ставится $ для вывода по 9 функции
  47. ;Параметр - адрес слова с адресом строки
  48. ;Возвращается в ax адрес первого слова, в слове с адресом строки
  49. ; возвращается адрес подстроки, начинающейся за первым словом или 0 для последнего слова
  50. ppStr equ [bp+4] ;адрес адреса строки
  51. FirstWord proc
  52. push bp
  53. mov bp, sp
  54. xor cx, cx ;адрес первого слова
  55. mov bx, ppStr ;адрес адреса строки
  56. mov si, [bx] ;адрес строки
  57. SearchBegin: ;цикл разбора строки
  58. lodsb ;очередной символ
  59. cmp al, 0dh ;конец строки
  60. je FW_last ;строка из одних пробелов
  61. cmp al, ' ' ;пробел?
  62. je SearchBegin ;первые пробелы обходим
  63. lea cx, [si-1] ;адрес начала слова
  64. SearchEnd: ;ищем конец слова
  65. lodsb ;очередной символ
  66. cmp al, 0dh ;конец строки
  67. je FW_last ;последнее слово
  68. cmp al, ' ' ;конец слова?
  69. jne SearchEnd ;ищем пробел после слова
  70. mov byte ptr [si-1], '$' ;поставим вместо пробела '$' для вывода
  71. jmp FW_ret ;на выход
  72. FW_last: ;последнее слово или одни пробелы
  73. mov byte ptr [si-1], '$' ;поставим вместо пробела '$' для вывода
  74. xor si, si ;больше слов нет
  75. FW_ret:
  76. mov [bx], si ;сохраним адрес второй подстроки или 0, если больше слов нет
  77. mov ax, cx ;возвращаем адрес первого слова для вывода
  78. pop bp
  79. ret 2 ;уберем из стека параметр
  80. FirstWord endp
  81. code ends
  82. data segment para public 'data'
  83. sString db 0ah,'Enter string: $'
  84. sResult db 0ah,0ah,'Words:',0dh,0ah,'$'
  85. sPress db 0dh,0ah,'Press any key$'
  86. ;буфер для ввода числовой строки (для функции 0ah)
  87. bMax db ? ;максимальный размер буфера
  88. bCount db ? ;реальный размер строки
  89. bString db 80 dup (?) ;сама строка
  90. wAddr dw ? ;адрес анализируемой строки
  91. data ends
  92. end start
какой механизм использован в 16-17 строках? мы вносим в bMax максимальное значение строки, а после туда же пишем строку, которую нам необходимо в будущем анализировать? если так, то как мы получаем доступ к этой строке в процедуре, если название bMax после нигде не используется. я, конечно, читал о структуре буфера. первый байт - максимальная длина строки, второй - фактическая, а с третьего идет сами данные.. как-то это взаимосвязано?)

Решение задачи: «Разбить заданную строку на две части»

textual
Листинг программы
  1. org 100h
  2. jmp start
  3.  
  4. mes0   db  13,10,'String: $'
  5. mes1   db  13,10,' Words: $'
  6. bMax   db  80               ; макс.размер буфера
  7. bLen   db  0                ; длина строки
  8. bStr   db  80 dup(0)        ; буфер источника
  9. buff   db  32 dup('$')      ; буфер приёмника
  10.  
  11. start:
  12.     mov   dx,mes0           ;
  13.     call  message           ;
  14.     mov   ah,0Ah            ; заполяем источник строкой юзера
  15.     mov   dx,bMax           ;
  16.     int   21h               ;
  17.  
  18.     mov   si,bStr           ; адрес начала строки для LODSB
  19. printWord:                  ;
  20.     call  findSpace         ; заполняем приёмный буфер
  21.     cmp   byte[buff],'$'    ; буфер пустой?
  22.     je    printWord         ;
  23.     mov   dx,mes1           ; в приёмнике что-то есть. мессага!
  24.     call  message           ;
  25.     mov   dx,buff           ; выводим данные из буфера
  26.     call  message           ;
  27.     jmp   printWord         ; ищем сл.слово в источнике
  28.  
  29. stop:                       ;
  30.     mov   al,7              ; бипер..
  31.     int   29h               ;
  32.     xor   ax,ax             ;
  33.     int   16h               ;
  34.     int   20h               ; выход!
  35.  
  36. ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн
  37. message: ;===================================================
  38.    mov   ah,9           ;
  39.    int   21h            ;
  40. ret                     ;
  41.  
  42. findSpace: ;=================================================
  43.     mov   cx,32         ; очистим приёмный буфер
  44.     mov   al,'$'        ;
  45.     mov   di,buff       ;
  46.     push  di            ;
  47.     rep   stosb         ;
  48. ;-----------------------;--
  49.     pop   di            ;
  50. @1: lodsb               ; читаем символ из SI
  51.     cmp   al,0Dh        ; всю строку юзера проверили?
  52.     je    endStr        ;
  53.     cmp   al,' '        ; пробел?
  54.     je    @2            ;
  55.     stosb               ; нет - сохраняем символ в приёмнике
  56.     jmp   @1            ; сл.символ..
  57. @2:                     ;
  58. ret                     ; выход из процедуры!
  59. endStr:                 ; выход из внешнего цикла!
  60.     pop   ax            ; снимаем CALL'овский адрес возврата
  61.     jmp   stop          ;

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 3.833 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы