CALL和RET指令(1)

Call指令

作用:调用子程序
实质:流程转移
call指令实现转移得方法和jmp指令的原理相似
格式:call标号
CPU执行call指令,进行两步操作:
(1)将当前的IP或CS和IP压入栈中
(2)转移

call标号
CPU执行此种格式的call指令时,进行如下的操作:
(1)(sp)=(sp)-2
((ss)*16+(sp))=(IP)
(2)(IP)=(IP)+16位位移
16位位移=标号处的地址-call指令后的第一个字节的地址;
16位移位移的范围-32768~32767;
16位位移由编译程序在编译时算出;
之前的博客中我们讲过jmp指令的运转方式
那这里类似于
push IP
jmp near ptr 标号(段内转移)

“Call far ptr 标号”实现的是段间转移

其操作过程
(1)(sp)=(sp)-2;
((ss)*16+(sp))=(CS)
(sp)=(sp)-2
((ss)*16+(sp))=(IP)
(2)(CS)=标号所在段的地址
(IP)=标号在段中的偏移地址

相当于:
push CS
push IP
jmp far ptr 标号(段间转移)

转移地址在寄存器中的call指令

指令格式:
call 16位reg
功能:
(sp)=(sp)-2
((ss)*16+(sp))=(IP)
(IP)=(16位reg)

相当于:
push IP
jmp 16位 reg

转移地址在内存中的call指令

(1)call word ptr 内存单元地址
用汇编语法来解释此种格式的call指令
CPU执行“call word ptr 内存单元地址“时。相当于进行:
push IP
jmp word ptr 内存单元地址
Ag:
mov sp,10H
mov ax,0123H
mov ds:[0],ax
call word ptr ds:[0]
执行后
IP=0123H
sp=0EH

(2)call dword ptr 内存单元地址
用汇编语法来解释此种格式的call指令
CPU执行“call dword ptr 内存单元地址“时。相当于进行:
push CS
push IP
jmp dword ptr 内存单元地址
Ag:
mov sp,10H
mov ax,0123h
mov ds:[0],ax;低地址放偏移地址
mov word ptr ds:[2],0;高地址存放段地址
call dword ptr ds:[0]
执行后CS=0
IP=0123H
sp=0CH

ret和retf

ret指令用栈中的数据,修改IP的内容,从而实现近转移
rerf指令用栈中的数据,修改CS和IP的内容,从而实现远转移
CPU执行ret指令时
(1)(IP)=((ss)*16+(sp))
(2)(sp)=(sp)+2
相当于:
POP IP
Ag
CALL和RET指令(1)_第1张图片上图中在mov bx,0后少写了
ret这里注意一下

CPU执行retf指令时
(1)(IP)=((ss)*16+(sp))
(2)(sp)=(sp)+2
(3)(CS)=((ss)*16+(sp))
(4)(sp)=(sp)+2

相当于:
POP IP
POP CS
Ag
CALL和RET指令(1)_第2张图片

call和ret的配合使用

具有子程序的源程序的框架如下
assume cs:code
code segment
main:

call sub1 ;调用子程序 sub1

mov ax,4c00h
int 21h

sub1:

call sub2

ret

sub2

ret

code ends
end main

我们通过问题来加深前面的理解
计算2的N次方

CALL和RET指令(1)_第3张图片CALL和RET指令(1)_第4张图片
CALL和RET指令(1)_第5张图片
我们执行命令后看到IP的值确实返回了

CALL和RET指令(1)_第6张图片
同时算出的值在BX中

但是有个问题
我们观察到这个栈段,使它随机分配的,这是很危险的,可能有时候是运行不了的

正确的程序
CALL和RET指令(1)_第7张图片CALL和RET指令(1)_第8张图片CALL和RET指令(1)_第9张图片
我们通过d命令去看一下,执行call指令后栈中的数据
尾部A3 01
的确是压栈了

mul指令

前面的博客中我写了关于div的除法指令
这里mul就是乘法指令
(1)两个相乘的数:两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8位reg或内存字节单元中;如果是16位,一个默认在AX中,另一个放在16位reg或内存子单元中
(2)结果:如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认在DX中存放,低位在AX中放

格式如下;
mul reg
mul 内存单元
内存单元可以用不同的寻址方式给出
Ag
mul byte ptr ds:[0]
含义:(AX)=(AL)*((ds)*16+0)
mul word ptr [bx+si+8]
含义:(AX)=(AX)((ds)16+(bx)+(si)+8)结果的低16位
(DX)=(AX)((ds)16+(bx)+(si)+8)结果的高16位

你可能感兴趣的:(汇编学习,学习)