汇编_10 call 和 ret 指令

上传人:油条 文档编号:49433331 上传时间:2018-07-27 格式:PPT 页数:43 大小:251KB
返回 下载 相关 举报
汇编_10 call 和 ret 指令_第1页
第1页 / 共43页
汇编_10 call 和 ret 指令_第2页
第2页 / 共43页
汇编_10 call 和 ret 指令_第3页
第3页 / 共43页
汇编_10 call 和 ret 指令_第4页
第4页 / 共43页
汇编_10 call 和 ret 指令_第5页
第5页 / 共43页
点击查看更多>>
资源描述

《汇编_10 call 和 ret 指令》由会员分享,可在线阅读,更多相关《汇编_10 call 和 ret 指令(43页珍藏版)》请在金锄头文库上搜索。

1、第10章 call 和 ret 指令n10.1 ret 和 retfn10.2 call 指令n10.3 依据位移进行转移的call指令n10.4 转移的目的地址在指令中的call指令n10.5 转移地址在寄存器中的call指令n10.6 转移地址在内存中的call指令n10.7 call 和 ret 的配合使用n10.8 mul 指令n10.9 模块化程序设计n10.10 参数和结果传递的问题n10.11 批量数据的传递n10.12 寄存器冲突的问题引言ncall和ret 指令都是转移指令,它们都修 改IP,或同时修改CS和IP。n它们经常被共同用来实现子程序的设计 。10.1 ret 和

2、retfnret指令用栈中的数据,修改IP的内容,从 而实现近转移; 操作nretf指令用栈中的数据,修改CS和IP的内 容,从而实现远转移; 操作10.1 ret 和 retfnCPU执行ret指令时,进行下面两步操作: (1)(IP)=(ss)*16+(sp) (2)(sp)=(sp)+210.1 ret 和 retfnCPU执行retf指令时,进行下面两步操作: (1)(IP)=(ss)*16+(sp) (2)(sp)=(sp)+2 (3)(CS)=(ss)*16+(sp) (4)(sp)=(sp)+210.1 ret 和 retfn用汇编语法来解释ret和retf指令: CPU执行re

3、t指令时,相当于进行:pop IP CPU执行retf指令时,相当于进行:pop IPpop CS10.1 ret 和 retfn示例程序 ret指令程序中ret指令执行后,(IP)=0,CS:IP 指向代码段的第一条指令。 retf指令程序中retf指令执行后,CS:IP指向代码段 的第一条指令。10.2 call 指令nCPU执行call指令,进行两步操作: (1)将当前的 IP 或 CS和IP 压入栈中; (2)转移。ncall 指令不能实现短转移,除此之外,call指 令实现转移的方法和 jmp 指令的原理相同, 下面的几个小节中 ,我们以给出转移目的地 址的不同方法为主线,讲解cal

4、l指令的主要应 用格式。10.3 依据位移进行转移的call指令ncall 标号n将当前的 IP 压栈后,转到标号处执行指令 (1) (sp) = (sp) 2(ss)*16+(sp) = (IP) (2) (IP) = (IP) + 16位位移 相当于: push IP jmp near ptr 标号10.3 依据位移进行转移的call指令ncall 标号 16位位移=“标号”处的地址call指令后 的第一个字节的地址; 16位位移的范围为 -3276832767,用 补码表示; 16位位移由编译程序在编译时算出。10.4 转移的目的地址在指令中的 call指令nCPU执行“call far

5、 ptr 标号”这种格式 的call指令时的操作: (1) (sp) = (sp) 2(ss) 16+(sp) = (CS)(sp) = (sp) 2(ss) 16+(sp) = (IP) (2) (CS) = 标号所在的段地址(IP) = 标号所在的偏移地址10.4 转移的目的地址在指令中的 call指令n用汇编语法来解释此种格式的 call 指 令:CPU 执行指令 “call far ptr 标号” 时,相当于进行:push CSpush IPjmp far ptr 标号10.5 转移地址在寄存器中的call 指令n指令格式:call 16位寄存器 功能:n(sp) = (sp) 2n(

6、ss)*16+(sp) = (IP)n(IP) = (16位寄存器) 相当于进行: push IP jmp 16位寄存器10.6 转移地址在内存中的call指令n转移地址在内存中的call指令有两种 格式: (1) call word ptr 内存单元地址 (2) call dword ptr 内存单元地址10.6 转移地址在内存中的call指令n(1) call word ptr 内存单元地址 汇编语法解释:push IPjmp word ptr 内存单元地址 示例10.6 转移地址在内存中的call指令n(1) call word ptr 内存单元地址(示例 ) 比如下面的指令:mov s

7、p,10hmov ax,0123hmov ds:0,axcall word ptr ds:0 执行后,(IP)=0123H,(sp)=0EH10.6 转移地址在内存中的call指令n(2) call dword ptr 内存单元地址 汇编语法解释:push CSpush IPjmp dword ptr 内存单元地址 示例10.6 转移地址在内存中的call指令n(2) call dword ptr 内存单元地址(示 例) 比如,下面的指令:mov sp,10hmov ax,0123hmov ds:0,axmov word ptr ds:2,0call dword ptr ds:0执行后,(CS

8、)=0,(IP)=0123H, (sp)=0CH10.7 call 和 ret 的配合使用 应用于子程序assume cs:code code segment start: mov ax,1mov cx,3call smov bx,ax ;(bx) = ?mov ax,4c00hint 21hs: add ax,axloop sret code ends end startn问题10.1 右面程序返回前, bx中的值是多少?10.7 call 和 ret 的配合使用n子程序的框架:标号:指令retn具有子程序的源程序的框架 :10.8 mul 指令n格式如下:mul regmul 内存单元:

9、(1)相乘的两个数:要么都是8位,要么都是16位。8 位: AL中和 8位寄存器或内存字节单元中;16 位: AX中和 16 位寄存器或内存字单元中。 (2)结果8位:AX中;16位:DX(高位)和AX(低位)中。10.8 mul 指令n内存单元可以用不同的寻址方式给出,比如: mul byte ptr ds:0含义为: (ax)=(al)*(ds)*16+0); mul word ptr bx+si+8含义为: (ax)=(al)*(ds)*16+(bx)+(si)+8)结果的低16位;(dx)=(al)*(ds)*16+(bx)+(si)+8)结果的高16位;10.8 mul 指令n例如:

10、 (1)计算100*10100和10小于255,可以做8位乘法,程 序如下:mov al,100mov bl,10mul bl结果: (ax)=1000(03E8H) 10.8 mul 指令n例如: (1)计算100*10000100小于255,可10000大于255,所以必须 做16位乘法,程序如下:mov ax,100mov bx,10000mul bx结果: (ax)=4240H,(dx)=000FH(F4240H=1000000)10.9 模块化程序设计ncall 与 ret 指令共同支持了汇编语言 编程中的模块化设计。n利用 call和ret指令,我们可以用简洁 的方法,实现多个互相

11、联系、功能独立 的子程序来解决一个复杂的问题。10.10 参数和结果传递的问题n子程序一般都要根据提供的参数处理一 定的事务,处理后,将结果(返回值) 提供给调用者。n重点在于如何存储子程序需要的参数和 产生的返回值。 10.10 参数和结果传递的问题n我们设计一个子程序,可以根据提供的 N,来计算N的3次方。n这里有两个问题: (1)我们将参数N存储在什么地方? (2)计算得到的数值,我们存储在什么地 方?10.10 参数和结果传递的问题n很显然,我们可以用寄存器来存储,可以 将参数放到 bx 中 ;因为子程序中要计 算 NNN ,可以使用多个 mul 指令, 为了方便,可将结果放到 dx

12、和 ax中。n子程序10.10 参数和结果传递的问题n子程序: 说明:计算N的3次方 参数: (bx)=N 结果: (dx:ax)=N3cube:mov ax,bxmul bxmul bxret10.10 参数和结果传递的问题n注意,我们在编程的时候要注意良好的 风格,对于程序应有详细的注释。子程 序的注释信息应该包含对子程序的功能 、参数和结果的说明。n因为今天写的子程序,以后可能还会用 到;自己写的子程序,也很可能要给别 人使用,所以一定要有全面的说明。 10.10 参数和结果传递的问题n编程:计算data段中第一组数据的 3 次方 ,结果保存在后面一组dword单元中。assume cs

13、:codedata segmentdw 1,2,3,4,5,6,7,8dd 0,0,0,0,0,0,0,0data endsn我们可以用到已经写好的子程序程序代码10.11 批量数据的传递n参数较多的情况下,将批量数据放到内 存中,然后将它们所在内存空间的首地 址放在寄存器中,传递给需要的子程序 。n对于具有批量数据的返回结果,也可用 同样的方法。 10.11 批量数据的传递n我们看一个例子,设计子程序 功能:将一个全是字母的字符串转化为大写。 子程序10.11 批量数据的传递n编程:将data段中的字符串转化为大 写。 源程序代码 注意:除了寄存器传递参数外,还有一 种通用的方法使用栈来传递

14、参数。10.12 寄存器冲突的问题n设计一个子程序: 功能:将一个全是字母,以0结尾的字符串,转 化为大写。 分析应用这个子程序 ,字符串的内容后面定要有一 个0,标记字符串的结束。子程序可以依次读取 每个字符进行检测,如果不是0,就进行大写的 转化,如果是0,就结束处理。由于可通过检测0而知道是否己经处理完整个字 符串 ,所以子程序可以不需要字符串的长度作 为参数。我们可以用jcxz来检测0。 10.12 寄存器冲突的问题n子程序设计: 说明:将一个全是字母,以0结尾的字 符串,转化为大写。 参数:ds:si指向字符串的首地址; 结果:没有返回值。 子程序代码10.12 寄存器冲突的问题n子

15、程序代码10.12 寄存器冲突的问题n程序的应用 (1)将data段中字符串转化为大写assume cs:codedata segmentdb conversation,0data ends 代码段中相关程序段如下:mov ax,datamov ds,axmov si,0call capital10.12 寄存器冲突的问题n子程序的应用 (2)将data段中字符串全部转化为大写assume cs:codedata segmentdb word,0db unix,0db wind,0db good,0data ends 可以看到,所有字符串的长度都是5(算上结 尾符 0 ),我们使用循环 ,重复

16、调用子程序 capital完成对4个字符串的处理。 完整的程序代码10.12 寄存器冲突的问题n问题10.2的错误在于:问题在于cx的使用,主程序要使用cx记录 循环次数,可是子程序中也使用了cx,在执 行子程序的时候,cx中保存的循环计数值被 改变,使得主程序的循环出错。从上而的问题中,实际上引出了个一般化的 问题:子程序中使用的寄存器,很可能在主 程序中也要使用,造成了寄存器使用上的冲 突。10.12 寄存器冲突的问题n解决方法:在子程序的开始将子程序中所 有用到的寄存器中的内容都保存起来,在子 程序返回前再恢复。我们可以用栈来保存寄 存器中的内容。 (1)编写调用了程序的程序的时候不必关心子 程序到底使用了哪些寄存器; (2)编写了程序的时候不必

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号