Последовательности символов, входящих в строку и расположенных в алфавитном или обратном алфавитному порядках - Assembler
Формулировка задачи:
Вывести на экран последовательности символов, входящих в строку и расположенных в алфавитном или обратном алфавитному порядках. Длина минимальной такой последовательности – 3 символа. Каждую имеющуюся последовательность выводить на экран с новой строки.
Мой код в спойлере. Ошибка заключается в том, что в обратном алфавитном порядке выводит немного неправильно. Помогите исправить.
Листинг программы
- .DATA
- String_1 db 40 dup(20h)
- String_2 db 40 dup(20h)
- Index_H dw 0000h
- Buffer dw 0000h
- Index_L dw 0000h
- In_Put db "Vvedite stroku, sostojawuu iz bukv v kolichesve ot 30 do 40 sivolov:",0Dh,0Ah,"$"
- Symbol_Bad_s db 0Dh,0Ah,"Vvedenno malo simvolov$"
- Clear db 62 dup(20h),"$"
- Enter db 0Dh,0Ah,"$"
- V_p db 0Dh,0Ah,"V Prjamom porjadke:","$"
- O_p db 0Dh,0Ah,"V Obratnom porjadke:","$"
- N_p db 0Dh,0Ah,"Elementy udovl. poisku otsutstvujut","$"
- Konec db 0Dh,0Ah,"Konec. Click ENTER","$"
- Count dw 0000h
- .STACK 256
- .CODE
- start:
- mov AX,@DATA
- mov DS,AX
- mov ES,AX
- mov DI,offset String_1
- mov DX,offset In_Put
- mov AH,09h
- int 21h
- mov CX,40
- InPut_Data:
- xor AH,AH ; Chtenie nagatoj klavishi
- int 16h
- cmp AL,0Dh ; Natat li ENTER?
- jz Symbol_Bad
- ; Proverka diapozona
- cmp AL,7Bh
- lahf
- not AH
- xchg AH,DH
- cmp AL,61h
- lahf
- or AH,DH
- sahf
- jns Indi ; Esli vvedennyje dannye in[a..z]
- cmp AL,5Bh
- lahf
- not AH
- xchg AH,DH
- cmp AL,41h
- lahf
- or AH,DH
- sahf
- jns Indi ; Esli vvedennyje dannye in[A..Z]
- ; Vyvod oshibki na ekran
- Symbol_Bad_PP:
- push CX
- mov AH,03h ; Nahojdenie pozicii kursora
- int 10h
- push DX
- mov DX,offset Symbol_Bad_s ; vyvod stroki oshibki
- mov AH,09h
- int 21h
- exit:
- xor AH,AH ; [AH=00h\ INT 16h] ==> ctenie najatpj klavishi
- int 16h
- cmp AL,0Dh ; Zaderjka do najatija Enter
- jnz exit
- mov AH,02h ; Peremeshenie kursora na nachalo stroki
- mov DX,0200h
- int 10h
- mov DX,offset Clear ; Ochistka stroki oshibki
- mov AH,09h
- int 21h
- pop DX ; Peremeshenie kursora na konec vvedennoj stroki
- mov AH,02h
- int 10h
- pop CX
- inc AH
- jmp Symbol_Bad
- Indi:
- mov AH,0Eh ; Vyvod vvedennoj stroki na ekran (Teletayp)
- int 10h
- stosb ; Zagruzka v stroku vvedennogo simvola
- inc Count
- Symbol_Bad:
- cmp Count,30
- jle InPut_Data
- cmp Count, 40
- jz Next
- cmp AL,0Dh
- jnz InPut_Data
- next:
- mov SI,offset String_1
- mov DI,offset String_2
- mov CX,Count
- Write:
- lodsb
- cmp AL,61h
- jae small ; big_Let ==> small_Let
- add AL,20h
- small:
- stosb
- loop Write
- mov SI,offset String_2 ; Zagruzka adresa pervogo simvola
- mov DI,offset String_2+1 ; Zagruzka adresa vtorogo simvola
- mov CX,Count
- cld
- mov DX,offset V_p
- mov AH,09h
- int 21h
- loads:
- lodsb ;AL,[SI] ; Poisk posledovatelnosni iz 2 simvolov v alfov. porjadke
- inc AL
- scasb ;[DI+1];AL
- loopnz loads
- xor CX,0
- jz exit_
- mov Index_L,SI ; Sohranenie pervogo elementa v alfov. porjadke
- re_loads: ; poisk poslednego elementa v alfov porjadke
- lodsb
- inc AL
- scasb
- loopz re_loads
- mov Index_H,SI ; Sohranenie adresa poslednego elementa
- mov Buffer,SI
- sub SI,Index_L
- cmp SI,2 ; kol-vo simvolov v alfov. porjadke
- jb prov ; Proverka (ne menee 3 simvolov)
- mov DX,offset Enter
- mov AH,09h
- int 21h
- push CX
- inc SI
- mov CX,SI
- mov AH,0Eh
- mov SI,Index_L
- sub SI,41
- write_skrin:
- lodsb ; vyvedenie simvolov
- int 10h
- loop write_skrin
- pop CX
- prov:
- mov SI,Index_H
- xor CX,0
- jnz loads
- exit_:
- xor Index_L,0
- jnz indicir
- mov DX,offset N_p ; esli net elementov, udovletvor. poisku
- mov AH,09h
- int 21h
- indicir:
- mov Index_H,0 ; Obnulenie Index_H
- mov SI,offset String_2-1 ; Zagruzka adresa poslednego elementa
- add SI,Count
- mov DI,SI
- dec DI
- mov CX,Count
- std
- ; V obratnom porjadke:
- mov DX,offset O_p
- mov AH,09h
- int 21h
- loads_:
- lodsb ;AL,[SI]
- inc AL
- scasb ;[DI+1];AL
- loopnz loads_
- xor CX,0
- jz exit__
- mov Index_H,SI
- inc Index_H
- re_loads_:
- lodsb
- inc AL
- scasb
- loopz re_loads_
- mov Index_L,SI
- mov Buffer,SI
- mov SI,Index_H
- sub SI,Index_L
- cmp SI,3
- jb prov_
- mov DX,offset Enter
- mov AH,09h
- int 21h
- push CX
- mov CX,SI
- mov AH,0Eh
- mov SI,Index_H
- sub Si,40
- write_skrin_:
- lodsb
- int 10h
- loop write_skrin_
- pop CX
- prov_:
- mov SI,Buffer
- xor CX,0
- jnz loads_
- exit__:
- xor Index_H,0
- jnz indicir_
- mov DX,offset N_p
- mov AH,09h
- int 21h
- indicir_:
- mov DX,offset Konec
- mov AH,09h
- int 21h
- _exit:
- xor AH,AH
- int 16h
- cmp AL,0Dh
- jnz _exit
- mov AX,4C00h
- int 21h
- end start
- ends
Решение задачи: «Последовательности символов, входящих в строку и расположенных в алфавитном или обратном алфавитному порядках»
textual
Листинг программы
- .model small
- .data
- InpBuff db 30, 0, 30 dup ('$')
- Kol db "Введите строку: ",'$'
- Vpyam db "По возрастанию: ","$"
- vobr db "По убыванию: ","$"
- .stack 256
- newstr macro
- call DispCrLf
- endm
- dosstr macro aStr:REQ
- mov dx, offset aStr
- call DispDt
- endm
- .code
- start PROC NEAR
- mov ax, @data
- mov ds, ax
- mov es, ax
- dosstr Kol
- newstr
- lea dx, InpBuff
- mov ah, 0ah
- int 21h
- newstr
- dosstr vpyam
- newstr
- xor cx, cx
- mov si, offset InpBuff+2
- mov di, offset IsDirSeq
- mov cl, [si-1]
- call SearchSequence
- dosstr vobr
- newstr
- mov di, offset IsRevSeq
- call SearchSequence
- @@exit:
- mov ax, 4c00h ; exit to operating system.
- int 21h
- start ENDP
- ;---------------------------
- SearchSequence PROC NEAR
- ; OnEnter:
- ; DS:SI-> string where look for sequence
- ; CX=StrLength
- ; CS:DI-> seearch sequence subrouting
- ; OnExit:
- ; AX=seqence length
- push ax
- push cx
- push si
- @@loop:
- call di
- test ax, ax
- jz @@end_of_str
- cmp ax, 3
- jb @@2next
- call OutStrLen
- call DispCrLf
- @@2next:
- add si, ax
- sub cx, ax
- jnz @@loop
- @@end_of_str:
- pop si
- pop cx
- pop ax
- ret
- SearchSequence ENDP
- ;---------------------------
- IsDirSeq PROC NEAR
- ; OnEnter:
- ; DS:SI-> string where look for sequence
- ; CX=StrLength
- ; OnExit:
- ; AX=seqence length
- ;
- push cx
- push dx ; seq cnt
- push si
- xor dx, dx
- jcxz @@exit
- cld
- inc dx
- lodsb
- dec cx
- jz @@exit
- @@loop:
- inc al
- mov ah, al
- lodsb
- cmp al, ah
- jne @@exit
- inc dx
- dec cx
- jnz @@loop
- @@exit:
- mov ax, dx
- pop si
- pop dx
- pop cx
- ret
- IsDirSeq ENDP
- ;---------------------------
- IsRevSeq PROC NEAR
- ; OnEnter:
- ; DS:SI-> string where look for sequence
- ; CX=StrLength
- ; OnExit:
- ; AX=seqence length
- ;
- push cx
- push dx ; seq cnt
- push si
- xor dx, dx
- jcxz @@exit
- cld
- inc dx
- lodsb
- dec cx
- jz @@exit
- @@loop:
- dec al
- mov ah, al
- lodsb
- cmp al, ah
- jne @@exit
- inc dx
- dec cx
- jnz @@loop
- @@exit:
- mov ax, dx
- pop si
- pop dx
- pop cx
- ret
- IsRevSeq ENDP
- ;---------------------------
- OutStrLen PROC NEAR
- ; OnEnter:
- ; DS:SI -> str to display
- ; AX -> str length
- push ax
- push cx
- push dx
- push si
- mov cx, ax
- cld
- jcxz @@exit
- @@loop:
- lodsb
- mov ah, 2
- mov dl, al
- int 21h
- loop @@loop
- @@exit:
- pop si
- pop dx
- pop cx
- pop ax
- ret
- OutStrLen ENDP
- ;---------------------------
- DispCrLf PROC NEAR
- push ax
- push dx
- mov dl, 0dh
- mov ah, 2
- int 21h
- mov dl, 0ah
- mov ah, 2
- int 21h
- pop dx
- pop ax
- ret
- DispCrLf ENDP
- ;---------------------------
- DispDt PROC NEAR
- push ax
- mov ah, 9
- int 21h
- pop ax
- ret
- DispDt ENDP
- ;---------------------------
- end start
Объяснение кода листинга программы
- Объявление модели
small
и переменных:InpBuff
- массив символов размером 30 байт, инициализированный нулямиKol
- строкаВведите строку:
Vpyam
- строкаПо возрастанию:
vobr
- строкаПо убыванию:
- Инициализация стека размером 256
- Макросы:
newstr
- вызов процедуры для пустой строкиdosstr
- подготовка аргумента, вывод на экран и переход на новую строку
- Процедура
start
:- Инициализация регистров ax, ds, es
- Вывод строки
Введите строку:
- Ввод строки с помощью прерывания int 21h
- Вывод строк
По возрастанию:
- Вызов процедуры
SearchSequence
для поиска последовательности по возрастанию - Вывод строк
По убыванию:
- Вызов процедуры
SearchSequence
для поиска последовательности по убыванию - Завершение программы с помощью прерывания int 21h
- Процедура
SearchSequence
:- Поиск последовательности символов во входной строке в алфавитном или обратном алфавитном порядке
- Процедуры
IsDirSeq
иIsRevSeq
:- Подпрограммы для поиска последовательности символов
по возрастанию
ипо убыванию
- Подпрограммы для поиска последовательности символов
- Процедура
OutStrLen
:- Вывод длины строки на экран
- Процедуры
DispCrLf
иDispDt
:- Вывод комбинации возврата каретки и перехода на новую строку
- Вывод строки на экран Этот код написан на языке Assembler, и он отвечает за ввод строки, поиск последовательности символов в алфавитном и обратном алфавитном порядках в этой строке, и вывод результатов на экран.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д