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

Объяснение кода листинга программы

  1. Объявление модели small и переменных:
    • InpBuff - массив символов размером 30 байт, инициализированный нулями
    • Kol - строка Введите строку:
    • Vpyam - строка По возрастанию:
    • vobr - строка По убыванию:
  2. Инициализация стека размером 256
  3. Макросы:
    • newstr - вызов процедуры для пустой строки
    • dosstr - подготовка аргумента, вывод на экран и переход на новую строку
  4. Процедура start:
    • Инициализация регистров ax, ds, es
    • Вывод строки Введите строку:
    • Ввод строки с помощью прерывания int 21h
    • Вывод строк По возрастанию:
    • Вызов процедуры SearchSequence для поиска последовательности по возрастанию
    • Вывод строк По убыванию:
    • Вызов процедуры SearchSequence для поиска последовательности по убыванию
    • Завершение программы с помощью прерывания int 21h
  5. Процедура SearchSequence:
    • Поиск последовательности символов во входной строке в алфавитном или обратном алфавитном порядке
  6. Процедуры IsDirSeq и IsRevSeq:
    • Подпрограммы для поиска последовательности символов по возрастанию и по убыванию
  7. Процедура OutStrLen:
    • Вывод длины строки на экран
  8. Процедуры DispCrLf и DispDt:
    • Вывод комбинации возврата каретки и перехода на новую строку
    • Вывод строки на экран Этот код написан на языке Assembler, и он отвечает за ввод строки, поиск последовательности символов в алфавитном и обратном алфавитном порядках в этой строке, и вывод результатов на экран.

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

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