Вывести из строки все слова с заданным символом (Tasm) - Assembler

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

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

Помогите, пожалуйста, отредактировать код. Условие задачи: ввести строку, ввести символ. Вывести все слова с данным символом. Прога выводит строку "Input", принимает сначала строку, потом символ и виснет.
.model small
.286
.stack 100h
.386
 
.data
  size_buf db 255
  size_real db 255
  string db 254 dup  ('$')
  newstr dw 53 dup ('$')
  
  i dw 0
  char db ?
  space db ' '
  ent db 10, 13, '$'
  newpos dw 0
  pos dw 0
  tmp dw ?
  message1 db "Input: $"
  ok db 0
 
.code
ENTER_PR proc
  push dx
  push ax
  lea dx, ent;
  mov ah, 09h
  int 21h
  pop ax
  pop dx
  ret
endp ENTER_PR

start:
    mov ax, @data
    mov ds, ax
 
;Вывод приглашения сделать вывод
   xor dx,dx
   mov DX,offset message1
   mov ah, 09h
   int 21h
   call ENTER_PR

  ;настроиться на str и считать строку
  lea dx, size_buf
  mov ah, 0Ah; считать строчку
  int 21h
 
  call ENTER_PR
 
;символ
   mov ah,01h
   int 21h
 
   mov char,al
   call ENTER_PR
   xor si,si
   lea si,string
 
  add si, 2 ;свдинулись на две ячейки вправо
  mov pos,si ;в позицию загоняем начальный адрес строки
  
  cycle:       
 
  mov cx, '$'
  cmp i,cx ;сравниваем на конец строки
  jae final ;если больше или равно мы идем на конец
  
  mov al,[si] ; ;перемещаем в аl первое значение по адресу
  cmp al,char ;сравниваем с символом
  jne second_cond ;если не равно, мы перескикиваем 
mov ok, 1  ;все ок
      
second_cond:    
      mov al,[si]  ;записываем значение по адресу
      cmp al,space  ;сравниваем с пробелом
      jne move ;не равно
 
      lea ax, ok
      cmp ax, 1
      jne ok_false
 
      lea di, string
      add di, 2  
      add di, pos  ;прибавляем позицию того слова, что содержит наш символ 
 
      lea bx, newstr
      add bx, 1 ;фактическая длина строки
 
    while1:       
      mov ax, i
      cmp pos, ax 
      jle end_while1    ; не больше/меньше или равно
 
      mov dl, byte ptr [di] 
      mov byte ptr [bx], dl  ;присваиваем символ одной строки, символу другой строки
      inc di
      inc bx
      inc pos
      jmp while1
 
end_while1: inc bx  ;добавляем новой строке пробел
      lea bx, space
      mov newpos, bx
 
ok_false:
      mov ok, 0
      mov ax, i
      mov pos, ax
      jmp move
 
move: inc i
      inc si
      jmp cycle
final:
  call ENTER_PR
 
  mov si,offset newstr
  int 21h
 
  mov ah, 4Ch
  int 21h
end start

Решение задачи: «Вывести из строки все слова с заданным символом (Tasm)»

textual
Листинг программы
;***************************************************************************;
;                               StrOutputWGC                                ;
;***************************************************************************;
;                                                                           ;
; Description:                                                              ;
;  The program takes a string, takes the character. Displays all words with ;
;  a given character.                                                       ;
;                                                                           ;
; Target OS:                                                                ;
;  MS-DOS (or in DOSBox, or else where).                                    ;
;                                                                           ;
; The code was written by XiloManX.                                         ;
; Created specially for [url]http://www.cyberforum.ru[/url].                           ;
; Compile with FASM v1.71.54.                                               ;
;                                                                           ;
; Rights of copying: is free.                                               ;
;                                                                           ;
; Date:                                                                     ;
;  30.10.2016                                                               ;
;                                                                           ;
;***************************************************************************;
 
;***************************************************************************;
;     *** HEAD AREA ***                                                     ;
;***************************************************************************;
 
format MZ
 
entry main:start            ; точка входа в программу.
stack 100h                  ; размер стека.
 
;***************************************************************************;
;     *** CONSTANTS AREA ***                                                ;
;***************************************************************************;
 
lf    equ 10       ; line feed.
cr    equ 13       ; carette return.
crlf  equ cr, lf   ; carette return and line feed.
 
;***************************************************************************;
;     *** DATA AREA ***                                                     ;
;***************************************************************************;
 
segment text
 
author_message  db  crlf, 'Written specially for [url]www.Cyberforum.ru[/url] by XiloManX.', crlf, crlf
author_message.length = $ - author_message
 
message:
 .crlf              db  cr, lf, '$'
 .for_input_line    db  'Enter line: '
 .for_input_char    db  'Enter char: '
 .for_output_line   db  'Result: '
 .for_notification  db  'Press any key to exit ...$'
 
buffer:
 .for_input_line    db  252, 0, 255 dup ('$')
 .for_output_line   db  255 dup ('$')
 .for_char          db  0
 
  src_pos           dw 0
  dst_pos           dw 0
 
;***************************************************************************;
;     *** CODE AREA ***                                                     ;
;***************************************************************************;
 
segment main
 
start:
        ; копируем адрес сегмента данных в сег. регистры ds и es.
        mov        ax, text
        mov        ds, ax
        mov        es, ax
        ; печатаем сообщение автора на экране.
        call       extra:print_author_message
        ; выводим приглашение сделать ввод строки.
        mov        cx, 12
        mov        bp, message.for_input_line
        mov        bx, 0eh ; attribute
        call       extra:print_text1
        ; переводим курсор на новую строку.
        call       extra:print_crlf
   read_line:
        ; считываем строку.
        push       dx
        mov        ah, 0ah
        mov        dx, buffer.for_input_line
        int        21h
        pop        dx
        ; проверим, был ли сделан ввод строки.
        cmp        [buffer.for_input_line+1], byte 1
        jle        read_line
        ; переводим курсор на новую строку.
        call       extra:print_crlf
        ; спускаем курсор на 2 ряда вниз.
        add        dh, 2
        xor        dl, dl
        ; выводим приглашение сделать ввод символа.
        mov        cx, 12
        mov        bp, message.for_input_char
        mov        bx, 0eh ; attribute
        call       extra:print_text1
        ; переводим курсор на новую строку.
        call       extra:print_crlf
   read_char:
        ; считываем символ.
        mov        ah, 01h
        int        21h
        ; проверим, был ли сделан ввод символа.
        cmp        al, byte 13
        je         read_char
        cmp        al, byte '$'
        jne        @f
        ; удаляем символ '$' и возвращаем курсор обратно.
    mov        ax, 13 ; cr.
    int        29h
    mov        ax, ' '
    int        29h
    mov        ax, 13 ; cr.
    int        29h
        jmp        read_char
     @@:
        ; сохраняем символ в буфер.
        mov        [buffer.for_char], al
        ; переводим курсор на новую строку.
        call       extra:print_crlf
        ; инициализируем bx, адресом буфера со строкой.
        lea        bx, [buffer.for_input_line+2]
        ; инициализируем dst_pos, адресом буфера назначения.
        push       buffer.for_output_line
        pop        [dst_pos]
 
    ; пропускаем пробел(ы).
    pass_space:
        cmp        [bx], byte '$'
        je         final
        cmp        [bx], byte ' '
        jne        save_start_addr
        inc        bx      
        jmp        pass_space
    ; сохраняем начальный адрес введёной строки.
    save_start_addr:
        mov        [src_pos], bx
    ; ищим символ в слове.
    seek_char:
        cmp        [bx], byte '$'
        je         final
        cmp        [bx], byte ' '
        je         pass_space
        mov        al, [buffer.for_char]  
        cmp        [bx], al ; сравниваем с символом.
        je         count_chars
        inc        bx      
        jmp        seek_char
   ; подсчитываем число символов в найдденом слове.
   count_chars:
        mov        bx, [src_pos]
        xor        cx, cx
     .cycle:
        cmp        [bx], byte '$'
        je         copy_chars
        cmp        [bx], byte ' '
        je         copy_chars
        inc        cl
        inc        bx      
        jmp        .cycle 
    ; копируем слово в буфер.
    copy_chars:
        mov        si, [src_pos]
        mov        di, [dst_pos]
        inc        cl
        rep        movsb
        dec        si  
        mov        bx, si
        mov        [dst_pos], di   
        jmp        pass_space
 
 
final:
        ; сохраняем символ конца строки.
        mov        [di-1], byte '$'
        ; переводим курсор на новую строку.
        call       extra:print_crlf
        ; спускаем курсор на 3 ряда вниз.
        add        dh, 3
        xor        dl, dl
        ; выводим сообщение.
        mov        cx, 8
        mov        bp, message.for_output_line
        mov        bx, 0ch ; цвет.
        call       extra:print_text1
        ; переводим курсор на новую строку.
        call       extra:print_crlf
        ; выводим строку.
        mov        dx, buffer.for_output_line
        call       extra:print_text2
        ; переводим курсор на новую строку.
        call       extra:print_crlf
        ; переводим курсор на новую строку.
        call       extra:print_crlf   
        ; выводим сообщение.
        mov        dx, message.for_notification
        call       extra:print_text2
        ; делаем паузу.
        mov        ah, 01h
        int        21h
        ; выходим из программы.
        mov        ah, 4Ch
        int        21h
 
;***************************************************************************;
;     *** PROCEDURE AREA ***                                                ;
;***************************************************************************;
 
segment extra
 
print_author_message:
        mov        bx, 0Ah     ; attribute.
        xor        dx, dx      ; cur pos.
        mov        cx, author_message.length
        mov        bp, author_message
; функция вывода текста на экран.
print_text1:
        mov        ax, 1301h   ; bit 1 - updare cursor.
        int        10h
        retf
; функция вывода текста на экран.
print_text2:
        mov        ah, 09h
        int        21h
        retf
; функция перевода курсора на новую строку.
print_crlf:
        mov        al, 13           ; CR.
        int        29h
        mov        al, 10           ; LF.
        int        29h
        retf

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


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

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

8   голосов , оценка 4.125 из 5
Похожие ответы