简体   繁体   中英

(Assembly 8086) How to display a letters from the stack?

I need to write a program that will get a letters from the user (console), until the letter 'Z' is entered (example: ABCZ). Letters must be placed on the stack. After completing the input, the program should print the letters from the stack in the reverse order (example: CBA), and then once again print the letters from the stack in alphabetical order (example: ABC). I wrote the program, but the last part works incorrectly. The program does not display letters from the stack in alphabetical order, except the first letter. I wanted to continue using SP after displaying it in reverse order.

    DATA SEGMENT
        MESSAGE DB "ENTER CHARACTER :$"
    DATA ENDS 

    SSEG SEGMENT STACK    
        DB 100H DUP (?)
    SSEG ENDS  

    CODE SEGMENT
        ASSUME CS:CODE, DS:DATA, SS:SSEG
    START:
        MOV AX,DATA
        MOV DS,AX 

        LEA DX,MESSAGE   ;print String or Message present in the
        MOV AH,9         ;character Array till $  symbol which 
        INT 21H          ;tells the compiler to stop.

        MOV CL,0         ;COUNTER 1
        MOV SI,0         ;COUNTER 2


    GET_CHAR: 
        MOV AH,1         ;read a character from console and save                          
        INT 21H          ;the value entered in variable CHAR in its ASCII form.
        MOV AH,0
        MOV BL,'Z'     
        CMP AL,BL
        JE  REV_PRINT
        PUSH AX
        INC CL
        INC SI
        JMP GET_CHAR

        PUSH BP           ;base pointer:  Offset address relative to SS

    REV_PRINT:    
        MOV BP,SP    
        CMP CL,0
        JE ABC_PRINT     
        MOV DX,[BP]
        MOV AH,02h        ;display the character that stored in DX.
        INT 21H
        ADD SP,2      
        DEC CL
        JMP REV_PRINT

    ABC_PRINT: 
        CMP SI,0
        JE EXIT 

        MOV AH,02h        ;display the character that stored in DX.
        INT 21H

        SUB SP,2
        MOV BP,SP         
        MOV DX,[BP]         
        DEC SI    
        JMP ABC_PRINT

    EXIT: 
        MOV AH,4CH       ;exit to dos or exit to operating system.
        INT 21H 

    CODE ENDS
        END START

在此处输入图片说明

Final Code after Ped7g helped me:

    DATA SEGMENT
        MESSAGE DB "ENTER CHARACTER :$"
    DATA ENDS 

    SSEG SEGMENT STACK    
        DB 100H DUP (?)
    SSEG ENDS  

    CODE SEGMENT
        ASSUME CS:CODE, DS:DATA, SS:SSEG
    START:
        MOV AX,DATA
        MOV DS,AX 

        LEA DX,MESSAGE   ;print String or Message present in the
        MOV AH,9         ;character Array till $  symbol which 
        INT 21H          ;tells the compiler to stop.

        MOV CL,0         ;COUNTER 1
        MOV SI,0         ;COUNTER 2


    GET_CHAR: 
        MOV AH,1         ;read a character from console and save                          
        INT 21H          ;the value entered in AX in its ASCII form.
        MOV AH,0
        MOV BL,'Z'     
        CMP AL,BL
        JE  PREP_TO_PRINT
        PUSH AX
        INC CL
        INC SI
        JMP GET_CHAR

    PREP_TO_PRINT:
        PUSH SI           ; store counter
        PUSH BP           ; base pointer:  Offset address relative to SS
        MOV  BP,SP
        ADD  BP,4         ; make it point to the last letter (BP+SI stored = 4B)
    REV_PRINT:
        TEST  CL,CL       ;until CL is not zero
        JE    ABC_PRINT
        MOV   DL,[BP]
        MOV   AH,02h      ;display the character that stored in DL.
        INT   21h
        ADD   BP,2
        DEC   CL
        JMP   REV_PRINT
    ABC_PRINT:
        TEST  SI,SI
        JE    EXIT
        SUB   BP,2        ; BP was +2 after first character
        MOV   DL,[BP]
        MOV   AH,02h      ;display the character that stored in DL.
        INT   21h
        DEC   SI
        JMP   ABC_PRINT
    EXIT:
        POP   BP          ; restore BP to original value (just for exercise)
    ; release all characters from stack (SP += 2*char_counter)
        POP   SI
        SHL   SI,1
        ADD   SP,SI
    ; here the SP should point to original value from before char input
    ; you may want to verify these assumptions in debugger,
    ; to see yourself how the stack works (also open memory view on ss:sp area)

        MOV AH,4CH       ;exit to dos or exit to operating system.
        INT 21H 

    CODE ENDS
        END START

In your reverse printing you do add sp,2 , freeing the stored letter from stack.

While it will technically stay in memory, the next int 21h (or any interrupt happening meanwhile) will use that stack memory to store return address and other internals, overwriting the old letter.

What you can do is to keep using bp to address stack (changing bp in print loop), but keep it also allocated by not freeing the letters until you printed them both ways (not changing sp meanwhile, only after everything is printed).

Like:

        ...
        JE  REV_PRINT
        PUSH AX
        INC CL
        INC SI
        JMP GET_CHAR

    REV_PRINT:
        PUSH SI           ; store counter
        PUSH BP           ; base pointer:  Offset address relative to SS
        MOV  BP,SP
        ADD  BP,4         ; make it point to the last letter (BP+SI stored = 4B)

    REV_LOOP:
        TEST  CL,CL
        JE    ABC_PRINT
        MOV   DL,[BP]
        MOV   AH,02h      ;display the character that stored in DL.
        INT   21h
        ADD   BP,2
        DEC   CL
        JMP   REV_LOOP

    ABC_PRINT:
        TEST  SI,SI
        JE    EXIT
        SUB   BP,2        ; BP was +2 after first character
        MOV   DL,[BP]
        MOV   AH,02h      ;display the character that stored in DL.
        INT   21h
        DEC   SI
        JMP   ABC_PRINT

    EXIT:
        POP   BP          ; restore BP to original value (just for exercise)
        ; release all characters from stack (SP += 2*char_counter)
        POP   SI
        SHL   SI,1
        ADD   SP,SI
        ; here the SP should point to original value from before char input
        ; you may want to verify these assumptions in debugger,
        ; to see yourself how the stack works (also open memory view on ss:sp area)
        ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM