1.call
近调用:即段内调用,只需得到偏移地址;
远调用:即段间调用,需得到段地址和偏移地址;
8086支持四种调用方式:
- 16位相对近调用:
call near task
、call task
、call 0x0500
机器码:E8 操作数
,操作数是偏移量(不是task、0x500),与IP运算后得到段内偏移地址;
操作数计算:task汇编地址-call汇编地址-3(指令长度) =>操作数因调用目标在call前或后可以为+、-=>操作数为16位有符号数=>操作数在[-32768,-32767]之间;
执行过程:原IP入栈,IP=IP+操作数+3,执行调用内容; - 16位间接绝对近调用:
call cx
、call [0x3000]
、call [bx]
机器码:FF 16 00 30
,操作数即为给出的偏移地址;
执行过程:访问DS:0x3000取出偏移地址替换IP内容,执行调用内容; - 16位直接绝对调用:
call 0x2000:0x0030
机器码:9A 30 00 00 20
执行过程:CS入栈、IP入栈、0x2000替换CS、0x0030替换IP、执行调用内容; - 16位间接绝对调用:
call far [0x2000]
、call far [bx]
、call far [addr]
假设addr dw 0x0102,0x2000
访问过程:CS、IP入栈,访问DS:addr,CS=0x2000,IP=0X0102,执行调用内容;
2.ret、retf
- ret:近返回指令,执行时处理器从栈中弹出一个字到IP中;
- retrf:远返回指令,执行时处理器从栈中弹出两个字到IP和CS中;
这样就可以返回调用位置继续执行,且ret,retf可以单独使用,从而访问栈。