Обработка строковых данных. Поменять местами два слова (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 ;
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д