Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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 程序集中另一个程序内的程序调用_Assembly_X86_Procedure - Fatal编程技术网

Assembly 程序集中另一个程序内的程序调用

Assembly 程序集中另一个程序内的程序调用,assembly,x86,procedure,Assembly,X86,Procedure,我正在使用tasm,试图在另一个过程中调用一个过程。但是,当程序从第二个过程返回时,IP设置为0000,而不是返回到调用它的点。有人能解释一下为什么会这样吗? 以下是代码的一部分: 主要程序: MAIN PROC FAR ; main proc MUST be FAR ASSUME CS:COD1,DS:DATA1,SS:STCK PUSH DS ;save DS on stack for OS return XOR AX,AX ; PUSH A

我正在使用tasm,试图在另一个过程中调用一个过程。但是,当程序从第二个过程返回时,IP设置为0000,而不是返回到调用它的点。有人能解释一下为什么会这样吗? 以下是代码的一部分:

主要程序:

MAIN    PROC    FAR ; main proc MUST be FAR

ASSUME  CS:COD1,DS:DATA1,SS:STCK
PUSH    DS      ;save DS on stack for OS return
XOR     AX,AX   ;
PUSH    AX      ;put 0 on stack for OS return
MOV     AX,DATA1
MOV     DS,AX   ;load data Segement register
CALL    PLAY
RET             ; return to OS

MAIN    ENDP
PLAY PROC NEAR
RPT:

MOV     AH,00H ;read ch from stdin
INT     16H
CMP     AH,48H
JE      UP
CMP     AH,4BH
JE      LEFT
CMP     AH,50H
JE      DOWN
CMP     AH,4DH
JE      RIGHT
CMP     AH,01H
JE      ESCAPE

UP:
CALL    MOVEUP
JMP     RPT

DOWN:
CALL    MOVEDOWN
JMP     RPT

LEFT:
CALL MOVELEFT
JMP RPT

RIGHT:
CALL MOVERIGHT
JMP RPT

ESCAPE:
RET

PLAY ENDP
MOVEUP PROC NEAR    ;tries to update position of player if down key pressed
PUSH    DX
PUSH    AX
PUSH    SI  ;save all general registers to stack

MOV     AL,X    ;compute index for current position
MOV     DL,15   
MUL     DL
MOV     DL,Y    
MOV     DH,0
ADD     AX,DX
MOV     SI,AX
PUSH    SI  ;save it for later


MOV     DL,  X  ;current x coord
MOV     DH,  Y  ;current y coord
SUB     DL,  1
MOV     NEWX,DL ;new x coord
MOV     NEWY,DH ;new y coord
MOV     AL,NEWX ;store new x coord in AL
MOV     AH,0    ;make ah 0 to "extend" new x on 2B
CMP     AL,0    ;check if new x in bounds (>=0)
JL      NOT_OK_UP

MOV     DL,15   ;compute index of position: index=15*x+y
MUL     DL
MOV     DL,NEWY 
MOV     DH,0
ADD     AX,DX
MOV     SI,AX
MOV     DL,MAZE[SI] ;fetch element on position newx,newy
CMP     DL,1        ;if wall, go to end of procedure(nop)

JE      NOT_OK_UP

MOV     DL,NEWX
MOV     DH,NEWY
MOV     X,DL    ;update x
MOV     Y,DH    ;update y
MOV     MAZE[SI],2  ;update position in maze
POP     SI
MOV     MAZE[SI],0  ;clean up old position
NOT_OK_UP:
POP     SI
POP     AX
POP     DX
RET
MOVEUP ENDP
第一个调用的过程:

MAIN    PROC    FAR ; main proc MUST be FAR

ASSUME  CS:COD1,DS:DATA1,SS:STCK
PUSH    DS      ;save DS on stack for OS return
XOR     AX,AX   ;
PUSH    AX      ;put 0 on stack for OS return
MOV     AX,DATA1
MOV     DS,AX   ;load data Segement register
CALL    PLAY
RET             ; return to OS

MAIN    ENDP
PLAY PROC NEAR
RPT:

MOV     AH,00H ;read ch from stdin
INT     16H
CMP     AH,48H
JE      UP
CMP     AH,4BH
JE      LEFT
CMP     AH,50H
JE      DOWN
CMP     AH,4DH
JE      RIGHT
CMP     AH,01H
JE      ESCAPE

UP:
CALL    MOVEUP
JMP     RPT

DOWN:
CALL    MOVEDOWN
JMP     RPT

LEFT:
CALL MOVELEFT
JMP RPT

RIGHT:
CALL MOVERIGHT
JMP RPT

ESCAPE:
RET

PLAY ENDP
MOVEUP PROC NEAR    ;tries to update position of player if down key pressed
PUSH    DX
PUSH    AX
PUSH    SI  ;save all general registers to stack

MOV     AL,X    ;compute index for current position
MOV     DL,15   
MUL     DL
MOV     DL,Y    
MOV     DH,0
ADD     AX,DX
MOV     SI,AX
PUSH    SI  ;save it for later


MOV     DL,  X  ;current x coord
MOV     DH,  Y  ;current y coord
SUB     DL,  1
MOV     NEWX,DL ;new x coord
MOV     NEWY,DH ;new y coord
MOV     AL,NEWX ;store new x coord in AL
MOV     AH,0    ;make ah 0 to "extend" new x on 2B
CMP     AL,0    ;check if new x in bounds (>=0)
JL      NOT_OK_UP

MOV     DL,15   ;compute index of position: index=15*x+y
MUL     DL
MOV     DL,NEWY 
MOV     DH,0
ADD     AX,DX
MOV     SI,AX
MOV     DL,MAZE[SI] ;fetch element on position newx,newy
CMP     DL,1        ;if wall, go to end of procedure(nop)

JE      NOT_OK_UP

MOV     DL,NEWX
MOV     DH,NEWY
MOV     X,DL    ;update x
MOV     Y,DH    ;update y
MOV     MAZE[SI],2  ;update position in maze
POP     SI
MOV     MAZE[SI],0  ;clean up old position
NOT_OK_UP:
POP     SI
POP     AX
POP     DX
RET
MOVEUP ENDP
第二个调用过程的模型:

MAIN    PROC    FAR ; main proc MUST be FAR

ASSUME  CS:COD1,DS:DATA1,SS:STCK
PUSH    DS      ;save DS on stack for OS return
XOR     AX,AX   ;
PUSH    AX      ;put 0 on stack for OS return
MOV     AX,DATA1
MOV     DS,AX   ;load data Segement register
CALL    PLAY
RET             ; return to OS

MAIN    ENDP
PLAY PROC NEAR
RPT:

MOV     AH,00H ;read ch from stdin
INT     16H
CMP     AH,48H
JE      UP
CMP     AH,4BH
JE      LEFT
CMP     AH,50H
JE      DOWN
CMP     AH,4DH
JE      RIGHT
CMP     AH,01H
JE      ESCAPE

UP:
CALL    MOVEUP
JMP     RPT

DOWN:
CALL    MOVEDOWN
JMP     RPT

LEFT:
CALL MOVELEFT
JMP RPT

RIGHT:
CALL MOVERIGHT
JMP RPT

ESCAPE:
RET

PLAY ENDP
MOVEUP PROC NEAR    ;tries to update position of player if down key pressed
PUSH    DX
PUSH    AX
PUSH    SI  ;save all general registers to stack

MOV     AL,X    ;compute index for current position
MOV     DL,15   
MUL     DL
MOV     DL,Y    
MOV     DH,0
ADD     AX,DX
MOV     SI,AX
PUSH    SI  ;save it for later


MOV     DL,  X  ;current x coord
MOV     DH,  Y  ;current y coord
SUB     DL,  1
MOV     NEWX,DL ;new x coord
MOV     NEWY,DH ;new y coord
MOV     AL,NEWX ;store new x coord in AL
MOV     AH,0    ;make ah 0 to "extend" new x on 2B
CMP     AL,0    ;check if new x in bounds (>=0)
JL      NOT_OK_UP

MOV     DL,15   ;compute index of position: index=15*x+y
MUL     DL
MOV     DL,NEWY 
MOV     DH,0
ADD     AX,DX
MOV     SI,AX
MOV     DL,MAZE[SI] ;fetch element on position newx,newy
CMP     DL,1        ;if wall, go to end of procedure(nop)

JE      NOT_OK_UP

MOV     DL,NEWX
MOV     DH,NEWY
MOV     X,DL    ;update x
MOV     Y,DH    ;update y
MOV     MAZE[SI],2  ;update position in maze
POP     SI
MOV     MAZE[SI],0  ;clean up old position
NOT_OK_UP:
POP     SI
POP     AX
POP     DX
RET
MOVEUP ENDP

如果执行“call”指令,则返回地址将被推送到堆栈上,如果执行“ret”指令,则地址将从堆栈中弹出。但是,如果我们在子例程内部使用“push”指令,而在末尾没有pop指令,那么堆栈顶部就不包含返回地址。因此,如果我们在从堆栈中弹出其他值之前执行“ret”指令,那么这些值将被用作返回地址。另一个问题是在一个子例程中调用一个子例程,而不控制我们使用了多少实例。为了增加Dirk的注释,标记为
PUSH SI
将其保存到以后的
,当你跳转到
NOT_OK\u UP
时,它不会再次正确弹出。我修改了代码,添加了正确的弹出窗口,现在就可以工作了。非常感谢您的解释和指出错误!