Обработка строковых данных. Поменять местами два слова (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                      ;

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

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