call

过程调用指令 CALL
指令格式:CALL OPRD
其中OPRD为过程的目的地址。
过程调用可分为段内调用和段间调用两种。寻址方式也可以分为直接寻址和间接寻址两种。
本指令不影响标志位。
<1>段内直接调用:CALL NEAR类型的过程名
每一个过程在定义时,应指定它是近类型(NEAR),还是远类型(FAR)。本指令是段内直接调用,因而过程与调用指令同处在一个代码段内。在执行该调用指令时,首先将IP的内容入栈保护,然后由指令代码给出的目的地址段内偏移量送入IP,从而实现过程调用,将程序转至过程入口。
<2>段内间接调用:CALL OPRD
其中OPRD为16位通用寄存器或存储器数。
本指令执行时,首先将IP的内容入栈保护,然后将目的地址在段内偏移量由指定的16位寄存器或存储器字中取至IP中,从而实现过程调用。
例如:CALL BX
CALL WORD PTR [BX+SI+20]
注意:寄存器间接调用时,寄存器不用方括号括起来。如果用方括号,则为存储器操作数间接调用。
<3>段间直接调用:CALL FAR类型的过程名
由于是段间调用,在指令执行时,应同是时将当前的CS及IP的值入栈保护,然后将FAR类型的过程名所在的段基址和段内偏移值送CS及IP,从而实现过程调用。
<4>段间间接调用:CALL DWOPRD
其中DWOPRD为存储器操作数,段间间接调用只能通过存储器双字进行。本指令执行时,首先将当前的CS及IP的值入栈保护,然后将存储器双字操作数的第一个字的内容送IP,将第二个字的内容送CS,以实现段间调用。
例如:CALL DWOPRD PTR[SI]
call和ret指令,它们都是转移指令,也都修改eip寄存器。他们经常的被用来实现在自程序设计。一般我们调用子程序都是通过call来实现的。 那么一般我们的call指令格式是 call 内存地址 这个内存地址就是我们子程序的地址,我们程序执行完call 内存 指令后,相应的eip=内存地址。 举例 call 00403020 执行指令后 eip寄存器= 00403020 。我们都直到我们的cpu每次读取数据执行都是先读取我们eip寄存器,然后定位内存地址,最后在将内存中的数据传送到指令缓存区,最后执行,那么相应eip也就+读取数据的字节大小。 但是转移指令是直接 eip = 转移的地址,例如我们之前学的jmp 和今天学的call 。 call最重要的还有一点是,这里我举例说明 假设此时call 00403020指令还没有执行。 假设此时cpu通过eip寄存器定位到


了call 00403020指令上,此时读取指令到指令缓冲区(注意:此时并没有开始执行,转移指令的eip值是变化两次的),新eip值= 旧eip +指令字节大小,此时我们cpu会将新eip的值压入堆栈。等待我们子程序执行完后,用ret指令将其之前eip值返回,从而使程序继续运行。。 最后

Word文档免费下载Word文档免费下载:call (共3页,当前第1页)

call相关文档

最新文档

返回顶部