Обработка строковых данных. Поменять местами два слова (tasm) - Assembler
Формулировка задачи:
Все слова в предложении имеют одинаковую длину. Заданы два целых положительных числа А и В. Это номера слов в предложении. Поменять местами эти два слова. Если, хотя бы одного слова с номером А или В нет, то сообщить об этом.
Помогите со сменой кода под задание в "индивидуальная часть программы". Спасибо.
DSEG SEGMENT
; индивидуальные данные - начало
k DW ?
j DW ?
A DB 'р'
N DW ?
POLE DB 20 dup(?),'$'
PRT3 DB 'номер слова -'
BUFFER1 DB 6 dup(?)
DB 10,13,'$'
; индивидуальные данные - конец
USER_STRING DB 100,101 dup(?)
TEXT1BW DB 'нет точки или ? или !',10,13,'$'
TEXT2BW DB 'неверный символ -'
SYMBW DB ?
DB ', его номер -'
buffer2 DB 6 dup(?)
DB 10,13,'$'
BWC DB ?
symb db ' ,:-.!?'
stroka DB 100 dup(?)
DB 10,13,'$'
prt1 DB 'введите предложение:',10,13,'$'
prt2 DB 10,13,'ввели предложение:',10,13,'$'
Prob db ' $'
NEW_LINE db 13,10,'$' ;перевод строки
Buffer db 6 dup (?),'$'
DSEG ENDS
Stacks segment
dw 140 dup (?)
Stacks ends
CODES SEGMENT
MAIN PROC FAR
Assume CS:codes, DS:dseg, SS:stacks,ES:dseg
Mov AX,Dseg
Mov DS,AX
mov ES,AX
CLD
LEA DX,prt1
Call PRT ;печать 'введите предложение: '
lea DI,STROKA ; очистили STROKA
mov CX,100
call CLEAR_STR
CALL READ_KEYS ; ввели предложение в USER_STRING
lea DI,STROKA
mov SI,DX
REP movsb ; переписали предложение в STROKA
lea DX,PRT2
call prt
lea DX,stroka
call prt
;*******************************************************************************
; индивидуальная часть программы - начало
; пусть i - BX
mov N,1
lea BX,STROKA
BL5:
mov k,BX
call END_WORD
mov j,BX
mov SI,k
mov AH,A
cmp byte ptr[SI],AH
je BL8
jmp BL12
BL8:
lea DI,POLE ; очистка POLE
mov CX,20
call CLEAR_STR
; перепись слова в POLE
mov CX,BX ; подсчет длины слова
sub CX,SI
inc CX
lea DI,POLE
REP movsb
; печать слова
lea DX,POLE
call PRT
push BX
mov AX,N
lea BX,BUFFER1
call convba
pop BX
lea DX,PRT3
call PRT
call NL
BL12:
inc N
call BEG_WORD
cmp BWC,0
je BL5
FIN:
; индивидуальная часть программы - конец
;*******************************************************************************
Mov AH,4CH
Int 21h
MAIN ENDP
;*********************************************************
CLEAR_STR proc ;процедура очистки поля
;адрес начала очищаемого поля в DI, количество символов в CX
push AX
push DI
push CX
mov AL,' '
REP STOSB
pop CX
pop DI
pop AX
RET
CLEAR_STR ENDP
;*********************************************************
CONVBA PROC ; процедура преобразования числа в строку ASCII-кода.
…
CONVBA endp
;*********************************************************
PRT PROC ; процедура печати текста
…
PRT ENDP
;*********************************************************
PRN PROC ;процедура печати числа
…
RET
PRN ENDP
;********************************************************
NL proc ; процедура перевода строки
…
NL endp
;*******************************************************
READ_KEYS proc ; процедура ввода строки в поле USER_STRING.
…
READ_KEYS endp
;*********************************************************
END_WORD proc
push SI
push AX
xor CX,CX
BEGEW:
push CX
mov CX,7
Lea SI,SYMB
COMP:
MOV AH,[SI]
CMP AH,[BX]
JE FINEW
INC SI
LOOP COMP
pop CX
inc BX
inc CX
JMP BEGEW
FINEW:
pop CX
dec BX
pop AX
pop SI
RET
END_WORD ENDP
;*******************************************************
BEG_WORD proc
push DX
push AX
lea DX,STROKA
add DX,100
mov BWC,0
inc BX ; переход на следующий символ после последнего в слове
mov AL,[BX]
cmp AL,'?' ; сравнение символа с '?' либо '!' либо '.'
je KONBW ; конец предложения
cmp AL,'!'
je KONBW
cmp AL,'.'
je KONBW
cmp AL,' ' ; сравнение с пробелом
je PROBBW
cmp AL,',' ; сравнение с ,
je GOPROBBW ; если запятая, то проверить наличие далее пробелов
cmp AL,'-' ; сравнение с -
; остается только символ :
GOPROBBW:
inc BX ; следующим должен быть пробел
cmp byte ptr[BX],' '
jne INVSYMBBW ; если не пробел - то это неверный символ
PROBBW: ; пропуск пробелов до начала следующего слова
inc BX
cmp BX,DX
jl M1BW
jmp ERRZICLBW ; в конце предложения нет '.' либо '?' либо '!'
M1BW:
cmp byte ptr[BX],' '
je PROBBW
jmp ENDPRBW
ERRZICLBW:
LEA DX,TEXT1BW
CALL PRT
mov BWC,1
jmp ENDPRBW
INVSYMBBW:
lea DX,TEXT2BW
mov AH,[BX]
mov SYMBW,AH
lea AX,STROKA
SUB AX,BX
neg AX
inc AX
lea BX,buffer2
call CONVBA
CALL PRT
KONBW:
mov BWC,1
ENDPRBW:
pop AX
pop DX
ret
BEG_WORD endp
;*********************************************
CODES ENDS
END MAINРешение задачи: «Обработка строковых данных. Поменять местами два слова (tasm)»
textual
Листинг программы
; fasm code.....
; Меняет местави слова в строке с указанными индексами
org 100h
jmp start
mes0 db 13,10,' Длинна слов...: $'
mes1 db 13,10,' Введите строку: $'
mes2 db 13,10,' Номер слова A.: $'
mes3 db 13,10,' Номер слова B.: $'
mes4 db 13,10,' --------------------'
db 13,10,' Результат.....: $'
mes5 db 07,' <--- Ошибка ввода! $'
buff db 80 dup('$') ; буфер для строки
bWord db 10 dup('$') ; ..и для слова
size dw 0 ; длина слова
count dw 0 ; кол-во слов в строке
possA dw 0 ; позиции слов
possB dw 0 ; ^
;-----------------------------------------------------------------------
start: mov ax,3 ; очистка экрана
int 10h ;
mov dx,mes0 ; первая операция
call message ;
mov ah,1 ;
int 21h ;
cmp al,'1' ; фильтр чисел (нуль не нужен)
jb start ;
cmp al,'9' ;
ja start ;
and ax,0fh ;
mov [size],ax ; запоминаем длину слов
push ax ;
mov dx,mes1 ;
call message ;
mov di,buff ;
xor bx,bx ;
pop dx ;
input: mov cx,dx ; ставим её циклом
mov ah,1 ;
sWord: int 21h ; вводим строку..
cmp al,13 ; ..до Enter
je begin ;
stosb ;
loop sWord ;
mov al,' ' ; авто/разделитель слов
int 29h ;
stosb ;
inc bx ; считаем кол-во слов
jmp input ;
begin: mov [count],bx ; запомним..
mov dx,mes2 ;
call message ;
call inputA ;
mov [possA],ax ; запоминаем А
mov dx,mes3 ;
call message ;
call inputA ;
mov [possB],ax ; запоминаем В
mov dx,mes4 ;
call message ;
;----------------------------------------------------------------
; Здесь нужно организовать обмен словами
;----------------------------------------------------------------
mov ax,[possA] ;
call getPosition ; SI - указатель на слово(А) в строке
push si ; (запомним его для обмена)..
mov di,bWord ; адрес приёмника
mov cx,[size] ; кол-во байт для копирования
rep movsb ; слово(А) в промежуточном буфере(С)
mov ax,[possB] ;
call getPosition ; SI - позиция слова(В) (источник)
pop di ; DI - приёмник
push si ;
mov cx,[size] ;
rep movsb ; замена слов: В --> A
mov si,bWord ;
pop di ;
mov cx,[size] ;
rep movsb ; замена слов: буфер(С) --> В
mov dx,buff ; выводим изменённую строку на экран
call message ;
;----------------------------------------------------------------
exit: xor ax,ax
int 16h
int 20h ; на выход!
;eeeeeeeeeeeeeeeee П Р О Ц Е Д У Р Ы eeeeeeeeeeeeeeeeeeeeeeeeeeee
message: ;
mov ah,9 ;
int 21h ;
ret ;
;----------------------------------------------------------------
inputA: mov ah,1 ; ввод А/В
int 21h ;
and ax,0fh ;
cmp ax,[count] ; ввод больше кол-ва слов?
jb okey ;
mov dx,mes5 ; да - ошибка!
call message ;
pop ax ; снимаем адрес возврата
jmp exit ; прощаемся..
okey: ret ; нет - выход из функции без ошибки!
getPosition:
mov bx,[size] ; длина слова
inc bx ; добавим пробел
mul bx ; АХ = позиция слова
sub ax,bx ; вычитаем разницу (т.к.отсчёт с нуля)
mov si,buff ;
add si,ax ; SI - указатель на начало слова
ret ;