ret和retf
ret指令实现近转移,会利用栈中的数据,修改ip的值
ret n指令相当于:
pop ip
add sp,n
也就是下面的过程:
(ip)=((ss)*16+(sp))
(sp)=(sp)+2
retf指令实现远转移
(ip)=((ss)*16+(sp))
(sp)=(sp)+2
(cs)=((ss)*16+(sp))
(sp)=(sp)+2
call
call指令执行的过程:
将当前ip或者cs和ip压入栈中
转移(jmp near或者call farptr)
所以call指令不能实现短转移,除此之外和jmp一样,常常和ret一起使用,机器码中不会显示绝对地址,而是计算后与目标地址的相对地址
call 相当于 jmp near
call farptr相当于jmp far
唯一的区别就是call的时候会,会将ip保存到栈中
call farptr的时候会把ip和cs同时压入到栈中
转移地址在内存中的call指令
(1)call word ptr 内存单元地址
(2)call dword ptr 内存单元地址
段地址放在高位,偏移地址放在低位
MUL指令
乘法指令
某个乘数默认是放在AL(或者AX)中,另外一个由后面的操作数给出
格式:
mul reg
mul 内存单元,内存单元可以由不同的寻址方式给出
相乘的两个数,要么是8位,要么都是16位
结果存放:
8位:AL中和8位寄存器或者内存字节单元中
结果放在AX中
16位:AX中和16位寄存器或者内存子单元中
DX(高16位)和AX(低16位)
有一点需要注意的是,ip始终指向本条指令的下一条指令的地址
在执行call的时候,首先会将下一条指令偏移地址压入栈中
在执行从内存单元寻址的时候,word ptr这个修饰只会决定从偏移地址往后读取几个字节
例题
assume cs:code
stack segment
dw 8 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ds,ax
mov ax,0
call word ptr ds:[0EH]
inc ax
inc ax
inc ax
mov ax,4c00h
int 21h
code ends
end start
执行之后ax为多少?