admin 管理员组文章数量: 1184232
2024年3月19日发(作者:尚硅谷java)
● CALL WORD PTR DESTIN 段间间接调用
执行操作:① (SP) ← (SP)-2,((SP)) ← (CS)当前
(SP) ← (SP)-2,((SP)) ← (IP)当前
● CALL FAR PTR <子程序名> 段间直接调用
执行操作:① (SP) ← (SP)-2,((SP)) ← (CS)当前
(SP) ← (SP)-2,((SP)) ← (IP)当前
② (IP) ← 偏移地址(在指令的第2、3个字节中)
(CS) ← 段地址(在指令的第4、5个字节中)
② (IP) ← (EA) ; (EA)为指令寻址方式所确定的有效地址
(CS) ← (EA+2)
② (IP) ← (EA) ; (EA)为指令寻址方式所确定的有效地址
② (IP) ← (IP)当前+16位位移量(在指令的第2、3个字节中)
● CALL DESTIN 段内间接调用
执行操作:① (SP) ← (SP)-2,((SP)) ← (IP)当前
1
2
0
1
6
2
8
1
4
2
⑵ CALL FAR PTR <子程序名> 远调用(far call)
远调用适用于调用程序(也称为主程序)和子程序不在同一段中的情况,所以也叫做
段间调用。和近调用指令一样,远调用指令中的寻址方式也可用直接方式和间接方式。
子程序存储在存储器中,可供一个或多个调用程序(主程序)反复调用。主程序调用子程
序时使用CALL指令,由子程序返回主程序时使用RET指令。由于调用程序和子程序可以
在同一个代码段中,也可以在不同的代码段中,因此,CALL指令和RET指令也有近调用、
近返回及远调用、远返回两类格式。
⑴ CALL NEAR PTR <子程序名> 近调用(near call)
近调用是CALL指令的缺省格式,可以写为"CALL <子程序名>rotine"。它调用同一个
代码段内的子程序(子过程),因此,在调用过程中不用改变CS的值,只需将子程序的地
址存入IP寄存器。CALL指令中的调用地址可以用直接和间接两种寻址方式表示。
⑶ RET 返回指令(return)
RET指令执行的操作是把保存在堆栈中的返回地址出栈,以完成从子程序返回到调用
程序的功能。
● CALL <子程序名> 段内直接调用
执行操作:① (SP) ← (SP)-2,((SP)) ← (IP)当前
从CALL指令执行的操作可以看出,第一步是把子程序返回调用程序的地址保存在堆
栈中。对段内调用,只需将IP的当前值,即CALL指令的下一条指令的地址存入SP所指
示的堆栈字单元中。对段间调用,保存返回地址则意味着要将CS和IP的当前值分别存入
堆栈的两个字单元中。
CALL指令的第二步操作是转子程序,即把子程序的入口地址交给IP(段内调用)或
CS:IP(段间调用)。对段内直接方式,调转的位移量,即子程序的入口地址和返回地址之
子程序的最后一条指令必须是RET指令,以返回到主程序。如果是段内返回,只需把
保存在堆栈中的偏移地址出栈存入IP即可,如果是段间返回,则要把偏移地址和段地址都
从堆栈中取出送到IP和CS寄存器中。
CALL指令和RET指令都不影响条件码。
● RET 段内返回(近返回)
执行操作:(IP) ← ((SP)),(SP) ← (SP)+2
● RET 段间返回(远返回)
执行操作:(IP) ← ((SP)),(SP) ← (SP)+2
(CS) ←((SP)),(SP) ← (SP)+2
● RET N 带立即数返回
执行操作:① 返回地址出栈(操作同段内或段间返回)
② 修改堆栈指针:(SP) ← (SP)+N
间的差值就在机器指令的2、3字节中。对段间直接方式,子程序的偏移地址和段地址就在
操作码之后的两个字中。对间接方式,子程序的入口地址就从寻址方式所确定的有效地址
中获得。
1
2
0
1
6
2
8
1
4
2
带立即数返回指令,除完成偏移地址出栈或偏移地址和段地址出栈的操作外,还要再
使SP的内容加上一个立即数N,使堆栈指针SP移动到新的位置。指令中的N可以是一个
常数,也可以是一个表达式。带立即数返回指令适用于C或PASCAL的调用规则,这些规
则在调用过程(子程序)前先把参数压入堆栈,子程序使用这些参数后,如果在返回时丢
弃这些已无用的参数,就在RET指令中包含一个数字,它表示压入到堆栈中参数的字节数,
这样堆栈指针就恢复到参数入栈前的值。
例3.43 根据下面调用程序和子程序的程序清单,画出RET指令执行前和执行后的堆栈
情况。假设初始的SS:SP=A000:1000。
0000 B8 001E MOV AX,30
0003 BB 0028 MOV BX,40
0006 50 PUSH AX ; push data1 into stack
0007 53 PUSH BX ; push data2 into stack
0008 E8 0066 CALL ADDM ; call <子程序名>
000B B4 02 MOV AH,2
… … …
0071 ADDM PROC NEAR ; entry point (IP)←0071=000b+0066
0071 55 PUSH BP ; save BP
0072 8B E4 MOV BP,SP ; addressing the stack with BP
0074 8B 46 04 MOV AX,[BP+4] ; get data2 from stack
0077 03 46 06 ADD AX,[BP+6] ; add data1
007A CD POP BP ; get back BP
版权声明:本文标题:子程序调用指令【精选】 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1710829133a575198.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论