整理自fishcc论坛
Call和Ret指令
ret指令:
使用栈中的数据,修改IP的内容,从而实现近转移(pop ip)
CPU执行ret指令时,进行如下操作:
1,(ip) = ((ss) * 16 + (sp))
2,(sp) = (sp) + 2
retf指令
用栈中的数据,修改CS和IP的内容,从而实现远转移(pop ip, pop cs)
CPU执行retf指令时,进行下面操作:
(IP)=((ss)*16+(sp))
(sp)=(sp)+2
(CS)=((ss)*16+(sp))
(sp)=(sp)+2
call指令
指令格式:
call 标号(将当前的IP压栈,转到标号处执行指令)
CPU执行call指令时,进行如下操作:
1,(sp) = (sp) - 2
2,((ss) * 16 + (sp)) = (IP)
3,(IP) = (IP) + 16位位移
(16位位移的计算:标号处地址 - call指令后的第一个字节的地址)
可以类比:call类似于C语言中函数调用,ret和retf类似于函数return语句
同样,指令“call far ptr 标号”实现的是段间转移。
CPU执行“call far ptr 标号”这种格式的call指令时的操作:
(1)
(sp) = (sp) – 2
((ss) ×16+(sp)) = (CS)
(sp) = (sp) – 2
((ss) ×16+(sp)) = (IP)
(2)
(CS) = 标号所在的段地址
(IP) = 标号所在的偏移地址
从上面的描述中可以看出,如果我们用汇编语法来解释此种格式的 call 指令,则:
CPU 执行指令 “call far ptr 标号” 时,相当于进行:
push CS
push IP
jmp far ptr 标号
转移地址在寄存器中的call指令
格式:call 16位寄存器
功能:
(sp) = (sp) – 2
((ss)*16+(sp)) = (IP)
(IP) = (16位寄存器)
汇编语法解释此种格式的 call 指令,CPU执行call 16位reg时,相当于进行:
push IP
jmp 16位寄存器
转移地址在内存中的call指令
转移地址在内存中的call指令有两种格式:
(1) call word ptr 内存单元地址
(2) call dword ptr 内存单元地址
(1) call word ptr 内存单元地址
汇编语法解释:
push IP
jmp word ptr 内存单元地址
(2) call dword ptr 内存单元地址
汇编语法解释:
push CS
push IP
jmp dword ptr 内存单元地址
call和ret指令的配合使用
assume cs:code
code segment
start:
mov ax,1
mov cx,3
call s
mov bx,ax ;(bx) = ?
mov ax,4c00h
int 21h
s: add ax,ax
loop s
ret
code ends
end start
(bx在执行完毕之后为8...)
mul指定
乘法命令
当相乘的两个数均为8位,这两个数应该放在AL中和8位寄存器或内存字节单元中,结果放在AX中(16位)
当相乘的两个数均为16位,这两个数应该放在AX中和16位寄存器或内存字节单元中,结果放在DX(高位)和AX(低位)中
使用格式:
mul reg
mul 内存单元
例子:
计算100 * 10000
mov ax,100
mov bx,10000
mul bx