Последовательности символов, входящих в строку и расположенных в алфавитном или обратном алфавитному порядках - 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, и он отвечает за ввод строки, поиск последовательности символов в алфавитном и обратном алфавитном порядках в этой строке, и вывод результатов на экран.