Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly (汇编8086)如何显示堆栈中的字母?_Assembly_Stack_X86 16 - Fatal编程技术网

Assembly (汇编8086)如何显示堆栈中的字母?

Assembly (汇编8086)如何显示堆栈中的字母?,assembly,stack,x86-16,Assembly,Stack,X86 16,我需要编写一个程序,从用户控制台获取一个字母,直到输入字母“Z”,例如:ABCZ。字母必须放在书堆上。完成输入后,程序应按相反顺序打印堆栈中的字母,例如:CBA,然后再次按字母顺序打印堆栈中的字母,例如:ABC。我写了程序,但最后一部分工作不正确。程序不按字母顺序显示堆栈中的字母,第一个字母除外。我想在按相反顺序显示SP后继续使用它 DATA SEGMENT MESSAGE DB "ENTER CHARACTER :$" DATA ENDS SSEG

我需要编写一个程序,从用户控制台获取一个字母,直到输入字母“Z”,例如:ABCZ。字母必须放在书堆上。完成输入后,程序应按相反顺序打印堆栈中的字母,例如:CBA,然后再次按字母顺序打印堆栈中的字母,例如:ABC。我写了程序,但最后一部分工作不正确。程序不按字母顺序显示堆栈中的字母,第一个字母除外。我想在按相反顺序显示SP后继续使用它

    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
Ped7g之后的最终代码帮助了我:

    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

在反向打印中,您确实添加了sp 2,将存储的字母从堆栈中释放出来

虽然从技术上讲,它将保留在内存中,但下一个int 21h或同时发生的任何中断将使用该堆栈内存存储返回地址和其他内部内容,覆盖旧的字母

您可以继续使用bp来解决打印循环中堆栈更改bp的问题,但也可以通过不释放字母来保持分配,直到您以两种方式打印它们为止。同时,只有在打印完所有内容后,才更改sp

比如:


@IgorOsipov你可能想接受答案,然后在左边靠近答案顶部的地方,让这个问题的答案对其他人有用,再加上增加我的声誉点数——如果你觉得它足够好的话。当然!我只是想完全发布你的代码。
        ...
        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)
        ...