0x00 调用call指令
执行该指令转向目的地的地址所指示的过程,并且这个过程执行完毕后,仍然返回到CALL指令的下一条指令地址,取指令继续执行原来的程序,因而也叫做过程调用指令。当然,该指令执行时,CPU首先将断点(IP或者CS:IP压入栈),然后以新的目的地址(即过程指令的首地址)装入IP或者CS:IP,于是控制转移到被调用的过程,与JMP指令一样,CALL指令也有段内和段间的直接调用和间接调用。调用过程也称作调用子程序。
- 段内直接调用
格式:
CALL NEAR PTR DST
功能:(SP)<——(SP)-2; SP-2
(SP)+1,(SP)<——IP; IP入栈
IP<——(IP)+16位位移量: 转向子程序入口
说明:第一步操作是把子程序返回地址(即CALL指令的下一条指令地址)压入堆栈,以便过程返回时使用;第二步操作是转移到被调用过程的入口地址去执行指令。指令中的DST为过程名,16位位移量是被调用过程入口地址与CALL指令的下一条指令地址之间的差值。
- 段内间接调用
格式:
CALL NEAR PTR DST
功能:(SP)<——(SP)-2 ;SP-2
(SP)+1,(SP)<——IP ;IP入栈
IP<——(EA); 转向子程序入口
说明:该指令与段内直接调用类似,区别在于IP的值不是由CALL指令的下一条指令地址加上16位位移量形成的。如果DST是16位通用寄存器操作数,则把寄存器内容送到IP:如果DST是字存储操作数则把存储单元的内容送IP。
例如:
CALL BX ; BX内容送IP
CALL WORD PTR [BX] ; (DS:BX)中读出一个字数据送IP
- 段间直接调用
格式:
CALL FAR PTR DST
功能:(SP)<——(SP)-2 ;SP-2
(SP)+1,(SP)<——CS ;CS压栈
SP<--(SP)-2 ;SP-2
(SP)+1,(SP)<——IP ;IP入栈
IP<-偏移地址 ;IP由指令中指定的偏移地址取代
CS<-段地址 ;CS由指令中指定的段地址取代
说明:该指令的操作与段内直接调用类似,不同的是:其一,调用时不仅要保护偏移地址,还要保护段地址,顺序是先CS压栈,再把IP压栈;其二,CS和IP的值不适用CALL指令的下一条指令地址位移量加上偏移量取代,而是直接将DST的段地址和偏移地址送入CS:IP
例如:
CALL 1000H:0100H ; 1000H直接送CS,0100H送IP
CALL FRA PTR SUB-PROC ; 过程SUB-PROC的段地址送CS,偏移送IP
- 段间间接调用
格式:
CALL FAR PTR DST
功能:(SP)<——(SP)-2 ;SP-2
(SP)+1,(SP)<——CS ;CS压栈
SP<--(SP)-2 ;SP-2
(SP)+1,(SP)<——IP ;IP入栈
IP<-(EA) ;EA取代IP中原地址
CS<-(EA+2) ;EA+2取代CS中原段地址
说明:该指令把段地址和偏移地址压栈保护,根据寻址方式求出EA后,把存储单元的字内容送到IP寄存器,并把下一个字的内容送到CS寄存器。
0x01 返回指令RET
格式:
RET
功能:
- 段内返回。
IP<-(SP)+1,SP
SP<-SP+2
- 段间返回
IP<-(SP)+1,SP
SP<-SP+2
CS<-(SP)+1,SP
SP<-SP+2