Вывести из строки все слова с заданным символом (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