Fork me on GitHub

转载:call和ret

转载自:http://hi.baidu.com/hypkb/blog/item/5031f781ea8ecad09023d96b.html

汇编语言笔记-第10章 call和ret指令

2009-02-02 17:59

 

ret指令用栈中的数据,修改IP的内容,从而实现近转移;
CPU执行ret指令时,进行下面两步操作:
(1)(IP)=((ss)*16+(sp))
(2)(sp)=(sp)+2
相当于进行:
pop IP
?
retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移;
CPU执行retf指令时,进行下面两步操作:
(1)(IP)=((ss)*16+(sp))
(2)(sp)=(sp)+2
(3)(CS)=((ss)*16+(sp))
(4)(sp)=(sp)+2
相当于进行:
pop IP
pop CS
?
CPU执行call指令,进行两步操作:
(1)将当前的 IP 或 CS和IP 压入栈中;
(2)转移.
call 指令不能实现短转移,除此之外,call指令实现转移的方法和 jmp 指令的原理相同.
?
call 标号(将当前的 IP 压栈后,转到标号处执行指令)
CPU执行此种格式的call指令时,进行如下的操作:
(1) (sp) = (sp) – 2
((ss)*16+(sp)) = (IP)
(2) (IP) = (IP) + 16位位移
16位位移=“标号”处的地址-call指令后的第一个字节的地址;
16位位移的范围为 -32768~32767,用补码表示;
16位位移由编译程序在编译时算出.
相当于进行:
push IP
jmp near ptr 标号
?
指令“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) = 标号所在的偏移地址
相当于进行:
push CS
push IP
jmp far ptr 标号
?
指令格式:call 16位寄存器
功能:
(sp) = (sp) – 2
((ss)*16+(sp)) = (IP)
(IP) = (16位寄存器)
相当于进行:
push IP
jmp 16位寄存器
?
call word ptr 内存单元地址
汇编语法解释:
push IP
jmp word ptr 内存单元地址
?
call dword ptr 内存单元地址
汇编语法解释:
push CS
push IP
jmp dword ptr 内存单元地址
?
可以写一个具有一定功能的程序段,我们称其为子程序,在需要的时候,用call指令转去执行.
call指令转去执行子程序之前,call指令后面的指令的地址将存储在栈中,所以可以在子程序的后面使用 ret 指令,用栈中的数据设置IP的值,从而转到 call 指令后面的代码处继续执行.
?
mul是乘法指令,使用 mul 做乘法的时候:
(1)相乘的两个数:要么都是8位,要么都是16位.
8 位: AL中和 8位寄存器或内存字节单元中;
16 位: AX中和 16 位寄存器或内存字单元中.
(2)结果
8位:AX中;
16位:DX(高位)和AX(低位)中.
格式如下:
mul reg
mul 内存单元
posted on 2013-03-24 19:35  loopever  阅读(179)  评论(0编辑  收藏  举报