汇编语言子程序设计.ppt
- 文档编号:5065542
- 上传时间:2023-05-08
- 格式:PPT
- 页数:84
- 大小:277KB
汇编语言子程序设计.ppt
《汇编语言子程序设计.ppt》由会员分享,可在线阅读,更多相关《汇编语言子程序设计.ppt(84页珍藏版)》请在冰点文库上搜索。
汇编语言子程序设计,汇编语言子程序设计基础概论过程与过程调用相关汇编语句子程序的参数传递方式局部变量处置与子程序设计递归、可再入程序与子程序设计,汇编语言子程序设计基础概论,现代计算机科学与汇编语言子程序设计程序模块的设计信息与汇编语言子程序,在计算机技术发展的较早时期,计算机系统中的程序可用资源极为有限,这使得如何压缩程序的系统资源占用成为程序设计所追求的重要目标;在现代,计算机系统中的程序可用资源极为丰富,这使得提高系统资源利用率已成为程序设计所追求的重要目标。
在计算机技术发展的较早时期,软件的规模极为有限,软件技术主要强调个人技艺;在现代,软件实现了商品化、规模急剧膨胀,工程化开发技术成为主流。
这些种种差异的存在导致了现代汇编语言子程序技术与传统间存在极大的不同。
为此,本章先讨论:
汇编语言子程序设计基础概论,现代汇编语言子程序设计与传统的主要区别以提高计算机应用系统的系统效率为基本出发点实现一个大型信息系统的底层模块可为高级语言程序所调用基于操作系统虚拟机实现追求程序的高质量(可读性、可移植、结构化、)追求开发工作的高效率具有可再入性(可再入子程序设计)局部资源的动态分配,汇编语言子程序设计基础概论,80x86系列机的汇编语言子程序设计特征存储器的分段管理(确立了子程序的高效工作模式)堆栈设置的系统特征(“基址指针”的特殊使用规则)子程序的硬件分类(近过程/远过程)主流处理器的流水作业操作系统的硬件支持机制主流操作系统多任务保护模式下的32位系统返回指令的“平衡堆栈”功能入口的“结构”对象操作支持,汇编语言子程序设计基础概论,程序模块的设计信息与汇编语言子程序模块化程序设计与汇编语言子程序程序模块的设计信息:
程序模块名程序模块的功能说明模块的参数设计模块所引用的其他模块列表模块的应用说明当软件的编程语言为C语言时,通常在相应工程文件中给出其“函数原型”模块的其他设计说明模块的测试数据系列及其设计说明,过程与过程调用相关汇编语句,80x86的子程序支持机制综述过程调用与返回指令子程序的组织与实例,作为一个面向数据处理应用设计的系列处理机,80x86的子程序支持机制是颇具特色的。
它既考虑了子程序作为一个软件产品的独立组成模块的软件工程需求,也考虑了其作为一个独立模块内部构件的程序实现需求;既考虑了直接的子程序调用的编程需要,也考虑了间接的子程序调用的编程需求;既考虑了子程序返回时的简单控制转移,也考虑了使用堆栈传递参数情况下返回控制时的堆栈平衡的需要。
学生在掌握这部分相关知识时,应当注意对之的系统把握。
本节将讨论以下几个问题:
过程与过程调用相关汇编语句,80x86的子程序支持机制综述近过程与远过程近过程子程序与主程序的代码在同一代码段内,两者间的控制转移(调用-返回)不改变CS内容远过程子程序与主程序有着各自的代码段,子程序的代码为系统中的“共享代码”,两者间的控制转移(调用-返回)将改变CS内容近过程附属于所从属的主程序,不是相应系统中的“共享代码”远过程的调用受到操作系统的监管远过程是可为高级语言程序调用的汇编语言子程序,而近过程不是远过程通常可被独立汇编,而近过程不能,过程与过程调用相关汇编语句,80x86的子程序支持机制综述过程的直接调用与间接调用过程的直接调用在直接给出被调用过程的名来引用被调过程(可类比于C语言程序中的一般“函数调用”语句)过程的间接调用在相应的主调程序的过程调用语句(指令)中通过“间接寻址”的方式(将被调过程的“指针”先行保存到一个寄存器/存储单元中,再在过程调用指令中通过该寄存器/存储单元间接地引用)来引用被调过程(可类比于C语言程序中的通过使用“指向函数的指针”调用函数)“间接调用”方式使主调模块可在一组具有相同外部特征的、同类型(同为“远过程”或者同为“近过程”)的被调过程中有选择地调用其中的某一个,过程与过程调用相关汇编语句,80x86的子程序支持机制综述过程返回时的“堆栈平衡”机制过程可被分为“有参过程”和“无参过程”有参过程的参数可通过堆栈传递,相关过程为:
主调模块将参数压入堆栈转移控制到被调过程被调过程从堆栈获取参数参数所占堆栈空间的释放“堆栈平衡”问题“堆栈平衡”可由主调模块完成也可由被调过程完成“堆栈平衡”只能发生在控制由被调过程转移到主调模块时或之后80x86处理机通过扩展“返回指令”的功能使过程返回时可实现“堆栈平衡”功能,过程与过程调用相关汇编语句,过程调用与返回指令过程调用指令段内直接调用的过程调用指令段内间接调用的过程调用指令段间直接调用的过程调用指令段间间接调用的过程调用指令过程调用指令属于“程序控制”指令组过程调用指令不影响任何标志过程调用指令所完成的操作:
将当前IP/EIP内容(返回地址)压入堆栈转移控制到被调用过程,过程与过程调用相关汇编语句,过程调用与返回指令段内直接调用的过程调用指令指令格式:
CALL机器指令中保存“地址差”(由汇编程序基于源程序中给出的“标号”产生,为2字节对象)Disp机器完成的操作:
(SP)-2SP,(IP)(SP)(IP)+DispIP“代码段寄存器”CS的内容不发生变化子程序的代码段与主程序的代码段在同一段中子程序的代码是主程序代码的一个相对独立成份作为“子程序名”的标号具有“NEAR”类型,过程与过程调用相关汇编语句,过程调用与返回指令段内间接调用的过程调用指令指令格式:
CALL指令中的为“字”类型,可为寄存器操作数或存储器操作数,存储器操作数的5种寻址方式均可用内容为绝对形式的目标IP值(为16位的无符号数)机器完成的操作:
(SP)-2SP,(IP)(SP)()IP当不能由其自身确定类型(“寄存器间接寻址”、“寄存器相对寻址”、“基址加变址寻址”或“相对基址加变址寻址”的存储器操作数)时,应当使用WORDPTR指定其“字”类型属性,过程与过程调用相关汇编语句,过程调用与返回指令段间直接调用的过程调用指令指令格式:
CALL机器指令中保存被调用过程的“长指针”(高16位被认为是确定段基址的数据,低16位被认为是目标IP)8086/88机器完成的操作:
(SP)-2SP,(CS)(SP)(SP)-2SP,(IP)(SP)(参数值高16位)CS(参数值低16位)IP子程序的代码段独立于主程序的代码段作为“子程序名”的标号具有“FAR”类型,过程与过程调用相关汇编语句,过程调用与返回指令段间直接调用的过程调用指令被调用过程是相应系统中的“共享代码”资源被调用过程的代码的“过程名”是一个外部定义的“标号”,通常需要用“FARPTR”来明确类型控制转移受到操作系统的监控主调模块与被调过程间的连接需通过相应的“连接程序”(属于操作系统的服务例程)来实现被调用的过程可以是主调模块所在软件产品中的独立模块,也可以是相应计算机系统中其他来源的模块或者操作系统中可被引用的共享代码在多任务系统中,如果被调过程是操作系统中的构件或“中间件”中的独立共享代码资源,则可能需要同操作系统的“调用门”关联门控机制的制约,过程与过程调用相关汇编语句,过程调用与返回指令段间间接调用的过程调用指令指令格式:
CALL指令中的在16位机器中为“双字”类型,只能是存储器操作数,存储器操作数的5种寻址方式均可用;当操作数的寻址方式为“直接寻址”时,除非已明确其类型为“双字”,否则,应使用“DWORDPTR”指定其类型;其它情况下,通常使用“DWORDPTR”来指定其类型8086/88机器完成的操作:
(SP)-2SP,(CS)(SP)(SP)-2SP,(IP)(SP)(参数值高16位)CS(参数值低16位)IP,过程与过程调用相关汇编语句,过程调用与返回指令段间间接调用的过程调用指令在80x86的32位保护模式下,“段间调用”类型的过程调用指令涉及到一个48位的操作数:
16位的“段选择子”确定段基地址32位的“段内偏移”这为访问操作系统中的可用代码资源提供了基础操作系统中可被应用程序使用的代码资源典型的是由操作系统定义的“调用门”(这时,“段选择子”指定的是一个确定的“调用门”的“门描述符”)有关进一步的细节参见“保护模式与汇编语言程序设计”部分的相应内容,过程与过程调用相关汇编语句,过程调用与返回指令86汇编程序对于过程调用指令的识别原则对于“直接”类型的过程调用指令的识别:
当被调用过程与调用过程名被用“FARPTR”指定其类型时,汇编程序使用“段间直接调用”当被调用过程与主调程序被组织在同一个源文件中、被调用过程先于主调程序的代码出现且被调用过程的“类型”为FAR时,汇编程序确认相应直接过程调用“段间直接调用”当被调用过程的过程名出现在主调程序的代码段内时,汇编程序确认相应直接过程调用为“段内直接调用”;被调用过程的过程名不出现在主调程序的代码段内时,汇编程序确认相应直接过程调用为“段间直接调用”,过程与过程调用相关汇编语句,过程调用与返回指令86汇编程序对于过程调用指令的识别原则对于“间接”类型的过程调用指令(16位机器)的识别:
当过程调用指令的“参数”被以“WORDPTR”指定类型时,相应的段间调用为“段内间接调用”;当过程调用指令的“参数”被以“DWORDPTR”指定类型时,相应的段间调用为“段间间接调用”当过程调用指令的“参数”为16位时,相应的段间调用为“段内间接调用”;当过程调用指令的“参数”为32位时,相应的段间调用为“段间间接调用”过程调用指令不影响标志过程返回指令不影响标志,过程与过程调用相关汇编语句,过程调用与返回指令段内返回指令:
格式:
RET机器执行指令时完成的操作:
(SP)IP(SP)+2SP段间返回指令:
机器执行指令时完成的操作:
(SP)IP(SP)+2SP(SP)CS(SP)+2SP,过程与过程调用相关汇编语句,子程序的组织汇编语言提供两条伪指令语句供组织一个过程的代码:
过程定义开始伪指令语句PROC过程定义结束伪指令语句ENDP过程定义开始伪指令语句放在一个过程的“体”(所有内容)之前,过程定义结束伪指令语句放在一个过程的“体”之后,如同一对括号括起一个过程的内容过程定义开始伪指令语句的格式:
过程名PROCNEAR|FAR过程定义结束伪指令语句的格式:
过程名ENDP“NEAR|FAR”用于指出一个过程的“类型”,过程的缺省类型为“NEAR”(近过程),过程与过程调用相关汇编语句,子程序的组织当一个过程为“近过程”时,其代码段将附属于其主调模块的代码段,应将其与主调模块的代码段与主调模块的代码段保存在同一源文件中当一个源文件包含一个主程序和若干子程序时,子程序的代码通常放在文件的开头部分以利汇编当一个过程为“远过程”时,较好的做法是将其保存在一个单独的原文件中,此时:
它可被独立汇编可方便地与其它模块连接为高级语言程序引用提供了基础在现代工程化开发软件的工作环境下,应当在每个过程的开头部分以“注释”的形式给出其系统的“说明信息”,以利相关过程的使用,也有利于软件质量的提高,过程与过程调用相关汇编语句,子程序的说明信息子程序说明信息一般由如下几部分组成,每一部分内容应简明确切:
子程序名功能描述入口和出口参数及其定义所用的寄存器和存储单元使用的算法和重要的性能指标其他调用注意事项和说明信息调用实例给出子程序的这些说明信息,有利于其被正确地使用子程序说明信息至少应该包含前三部分内容,过程与过程调用相关汇编语句,子程序的说明信息示例:
;子程序名:
AHTOASC;功能:
把8位二进制数转换为;2位十六进制数的ASCII码;入口参数:
AL=欲转换的8位二进制数;出口参数:
AH=十六进制数高位的ASCII码;AL=十六进制数低位的ASCII码;其他说明:
(1)近过程;
(2)除AX寄存器外,不影响其他寄存器;(3)调用了HTOASC实现;十六进制数到ASCII码的转换在看了上述关于子程序AHTOASC的说明信息后,即使不熟悉或不了解这个子程序本身,也就能够方便地调用它了。
过程与过程调用相关汇编语句,过程与过程调用相关汇编语句,子程序实例,例2:
写一个把16位二进制数转换为4位十六进制数ASCII码的子程序。
转换方法是:
把16位二进制数向左循环移位四次,使高4位成为低四位,析出低四位,调用子程序HTOASC转换出1位十六进制数的ASCII码,重复四次便完成转换。
子程序源代码如下:
;入口参数:
DX=欲转换的二进制数;DS:
BX=存放转换所得;ASCII码串的缓冲区首地址;出口参数:
十六进制数ASCII码串;按高位到低位依次存放在;指定的缓冲区中,过程与过程调用相关汇编语句,HTASCSPROCMOVCX,4HTASCS1:
ROLDX,1;循环左移4位ROLDX,1;高四位成为低四位ROLDX,1ROLDX,1MOVAL,DL;复制出低四位CALLHTOASC;转换得ASCII码MOVBX,AL;保存INCBX;调整缓冲区指针LOOPHTASCS1;重复四次RETHTASCSENDP用子程序HTASCS按16进制形式显示F000:
0000H的字单元内容的一个程序如下:
;程序名:
T4-1.ASM;功能:
(略)DSEGSEGMENT;数据段BUFFDB4DUP(0);存放4位十六进制数的ASCII码DBH,0DH,0AH,$;形成以$结尾的串DSEGENDSCSEGSEGMENT;代码段ASSUMECS:
CSEG,DS:
DSEGSTART:
MOVAX,DSEGMOVDS,AXMOVAX,0F000HMOVES,AXMOVDX,ES:
0;取指定内存单元的内容MOVBX,OFFSETBUFF;准备入口参数CALLHTASCS;变为4位16进制数ASCII码MOVDX,OFFSETBUFFMOVAH,9;调用9H号功能显示之INT21HMOVAX,4C00H;程序正常结束INT21H,过程与过程调用相关汇编语句,HTASCSPROC;内容略HTASCSENDP;HTOASCPROC;内容略HTOASCENDPCSEGENDSENDSTART,过程与过程调用相关汇编语句,子程序实例,例3:
写一个把16位二进制数转换为5位十进制数ASCII码的子程序。
为了简单起见,设二进制数是无符号的。
第3章中的程序T3-11.ASM实现“把16位二进制数转换为5位十进制的BCD码”,把BCD码转换为对应ASCII码是容易的,所以,可把T3-11.ASM改写成一个子程序。
但这里采用另一个算法把16位二进制数转换为5位十进制数的BCD码。
该算法是:
把16位二进制数除以10,余数是“个位”数的BCD码;把商再除以10,余数就是“十位”数的BCD码;如此,可依次得“百位”、“千位”和“万位”数的BCD码。
这可利用一个循环来控制。
;入口参数:
AX=欲转换的二进制数;DS:
BX=存放转换所得ASCII码串的缓冲区首地址;出口参数:
十进制数ASCII码串按万位到;个位的序依次存放在指定的缓冲区中BTOASCPROCMOVSI,5;置循环次数MOVCX,10;置除数10BTOASC1:
XORDX,DX;把被除数扩展成32位DIVCX;除操作ADDDL,30H;余数为BCD码,;转换为ASCII码DECSI;调整循环计数器MOVBXSI,DL;保存所得ASCII码ORSI,SI;判是否转换结束JNZBTOASC1;否,继续RETBTOASCENDP在上面的子程序中,寄存器SI既作计数器使用又作变址指针使用。
子程序的参数传递方式,80x86的子程序参数传递方式概述寄存器的保护与恢复利用寄存器传递子程序参数利用堆栈传递子程序参数,在现代汇编语言程序设计中,子程序技术是特别值得关注的,如前所述,实践要求一个计算机应用系统中的汇编语言子程序可为系统中用高级语言实现的模块所调用。
这使得虽然某些参数传递方式对于汇编语言程序来说也许是有益的,但将影响其与高级语言程序间的连接,由此在现代汇编语言程序设计中不合适使用。
本部分先概要地对子程序的参数传递方式作一讨论,然后讨论寄存器的保护与恢复问题作一基础性讨论,最后讨论常用的了两种子程序参数传递方式。
子程序的参数传递方式,80x86的子程序参数传递方式概述关于主程序与子程序的参数传递,有:
子程序可以是“无参”的,也可以带有多个参数,这完全由子程序确定。
或者说,一个子程序是否带有参数、带有多少个参数因子程序的不同而不同一个子程序的参数个数也可以是可变的在现代汇编语言程序设计中,主程序与子程序的参数传递方式一般而论可有三种:
利用寄存器传递参数子程序从确定的寄存器中获取主程序传来的参数利用约定的存储单元存底参数子程序从确定的存储器单元获取主程序传来的参数利用堆栈传递参数子程序从堆栈获取主程序传来的参数,子程序的参数传递方式,80x86的子程序参数传递方式概述当考虑到一个80x86汇编语言子程序需要被高级语言程序所调用时,应当满足的基本约束条件是:
子程序是一个远过程子程序不使用约定存储单元传递参数当子程序使用寄存器传递参数时,应当:
限制所使用寄存器个数不超过2个仅使用寄存器传递简单(单质)的参数当需要使用一个寄存器传递参数时,使用AL、AX或者EAX当需要用寄存器传递一个单质的、超过机器字长的参数时,可使用DX:
AX或者EDX:
EAX,子程序的参数传递方式,寄存器的保护与恢复汇编语言程序设计的突出特征之一就是要尽量利用寄存器对高效信息处理的支持主程序与子程序在使用寄存器上容易产生冲突现代模块化程序设计技术要求程序模块间保持良好的相对独立性,这在汇编语言程序设计中就包括了系统资源占用的独立性(高级语言程序设计中无此问题)当一个软件产品中的两个模块间存在调用关系时,则两者间就可能存在使用寄存器上的冲突,也就存在“寄存器的保护与恢复”问题,对之,有:
需要保护的是被调模块中使用的寄存器逻辑上,保护寄存器的工作可由主调模块实现也可由被调模块实现实践中通常由被调模块实现寄存器保护,子程序的参数传递方式,寄存器的保护与恢复保护寄存器的被调模块实现:
使用堆栈保护寄存器在被调模块的入口将要保护寄存器的内容入栈在返回控制前恢复已保护的寄存器的内容与之相关联,有:
需要保护哪些寄存器视子程序的实现而定是否需要保护保存入口参数的寄存器,由被调模块的设计者基于模块的逻辑特征与应用情况确定对于标志寄存器是否需要保护,有:
如果被调模块不使用标志作为出口参数,原则上需要保护由被调模块的设计者基于模块的应用情况确定,子程序的参数传递方式,寄存器的保护与恢复示例:
设计一个子程序检测一个指定输入缓冲区中的内容是否为一个十进制数字串。
说明:
被检测的字符串是用相应的DOS系统调用获得的输入的数字串可能有多个前导的“空格”字符,对之,子程序应当将其去掉(通过调用一个子程序)相关的子程序应当可被高级语言程序所调用下面先给出两个相关的子程序:
去除指定输入缓冲区中一个数字串的前导空格子程序检测一个输入串是否为十进制数字串子程序,子程序的参数传递方式,去除数字串前导空格子程序;子程序名:
ERSPSDG;功能:
去除一个数字串中的前导空格;入口参数:
DX数字串所在输入缓冲区的段值;AX数字串所在输入缓冲区的偏移;出口参数:
存放在给定的输入缓冲区中;说明:
输入缓冲区中的“串长度”为去除前导空格后;的输入串实际长度;调用实例:
MOVDX,;MOVAX,;CALLFARPTRERSPSDG,SPACEEQU20HERSPSDGPROCFARPUSHDS;保护寄存器PUSHSIPUSHCXPUSHDIPUSHBXPUSHAXMOVDS,DX;给定被处理串段值MOVSI,AX;给定被处理串偏移INCSIMOVDI,SIMOVAL,SI;获得输入串长MOVCL,ALXORCH,CHINCDI;准备结果保存指针JCXZERSP5;被处理串为“空”,转结束处理ERSP1:
INCSI;读出串内容MOVAL,SI,CMPAL,SPAC;检查是否前导空格LOOPZERSP1POPBX;保存实际串长JNZERSP2;处理数字串仅含1位数字情况ORCL,CLJZERSP3ERSP2:
INCCLERSP3:
MOVBX+1,CLPUSHBXORCL,CL;确认被处理串是否为空格串JNZERSP4MOVAL,SI+1;全空格串处理MOVDI,ALJMPSHORTERSP5;转结束处理ERSP4:
MOVAL,SI;保存去除前导空格后的数字串MOVDI,ALINCSIINCDILOOPERSP4,ERSP5:
POPAXPOPBXPOPDIPOPCXPOPSIPOPDSRETERSPSDGENDP,子程序的参数传递方式,检测十进制数字串子程序;子程序名:
TSPSDG;功能:
确认一个十进制数字串的合法性;入口参数:
DX数字串所在输入缓冲区的段值;AX数字串所在输入缓冲区的偏移;出口参数:
CF=0给定的字符串不是十进制数字串;CF=1给定的字符串是十进制数字串;说明:
输入缓冲区中的“串长度”为去除前导空格后的输;入串实际长度,即其所含十进制数字符个数;调用实例:
MOVDX,;MOVAX,;CALLFARPTRTSPSDG,ZEROEQU0NINEEQU9TSPSDGPROCFARPUSHDS;保护寄存器PUSHSIPUSHCXPUSHAXMOVDS,DX;给定被处理串段值MOVSI,AX;给定被处理串偏移INCSIMOVAL,SI;获得输入串长MOVCL,ALXORCH,CHJCXZTSPSD2;被处理串为“空”,转结束处理CALLERSPSDG;去掉串中可能存在的前导空格MOVAL,SIMOVCL,ALJCXZTSPSD2;被处理串为“空”,转结束处理,TSPSD1:
INCSI;从串中读出一个字符MOVAL,SIANDAL,01111111BCMPALZERO;该字符9JATSPSD2;是,相应字符不是数字符LOOPTSPSD1STC;1CFJMPSHORTTSPSD3TSPSD2:
CLC;0CFTSPSD3:
POPAX;恢复寄存器POPCXPOPSIPOPDSRETTSPSDGENDP,子程序的参数传递方式,关于子程序的参数关于一个子程序的参数,有:
就参数与子程序执行的任务间的关联而论,有:
入口参数为子程序需要处理的对象出口参数为子程序产生的、需要返回给主程序的参数就参数的程序组织特性而论,参数可被组织为三类:
in参数它们荷载子程序所要加工的数据值进入子程序out参数它们荷载子程序的加工结果返回主程序inout参数它们荷载子程序所要加工的数据值进入子程序,同时也把子程序的加工结果返回主程序就参数是否包含成员数据而论,可将参数划分为:
简单参数也称为“单质”参数,不含成员数据聚合参数也称为“成组”参数,包含成员数据,子程序的参数传递方式,关于子程序的参数关于一个子程序的参数,有:
对于子程序的出口参数,可进一步地划分为:
状态参数为子程序给出的状态标识数据参数为子程序所产生的计算结果就参数的程序设计归类而论,有:
数据参数参数的内容或者是子程序要加工的数据值或者是子程序的加工结果指针参数参数的内容是地址,其所指向的存储单元/存储单元组中保存着子程序要加工的数据值或者子程序的加工结果在程序设计实践中,尤其是在汇编语言程序设
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 子程序 设计