汇编语言-子程序_第1页
汇编语言-子程序_第2页
汇编语言-子程序_第3页
汇编语言-子程序_第4页
汇编语言-子程序_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

本章学习要点:(1)子程序的编写格式(2)子程序调用时的参数传递方法(3)嵌套及递归子程序一、过程定义语句(process)利用过程定义伪指令语句,可把程序片段说明为具有近类型或远类型的过程,并且能给过程取一个名字。过程定于语句的格式如下:过程名PROC[NEAR|FAR]…过程名ENDP过程的类型在过程定义开始语句PROC中指定;过程可以被指定位近(NEAR)类型,也可以被指定为远类型。如果不指定,则通常默认为近类型;定义一个过程的开始语句PROC和结束语句ENDP前使用的过程名称必须一致,从而保持配对。2021/5/91

像普通标号一样,过程名具有段值、偏移和类型这三个属性。

过程名的段值和偏移是对应过程入口(过程定义开始伪指令语句后的指令语句)的段值和偏移。 例:下面程序片段运行后,AL=?,BL=?。

XORAL,AL CALLSUBS MOVBL,AL CALLSUBS RCRAL,1 HLT ;停机,halt SUBSPROCNEAR NOTAL JSNEXT STC ;CF=1,

SeTCf=1 NEXT:RET SUBSENDP2021/5/92

例:用程序调用的方法,完成一个把16位二进制数转换为4位十六进制ASCII码的转换程序。 子程序说明:入口参数:DX=欲转换的二进制数;

DS:BX=存放转换所得ASCII码串的缓冲区首地址,转换后的ASCII码串按照高位到低位的次序存放在指定的缓冲区中。

HTASCSPROC RET MOVCX,4 HTASCSENDP

HTASCS1:ROLDX,1

HTOASCPROCNEAR

ROLDX,1

ANDAL,0FH

ROLDX,1

ADDAL,30H

ROLDX,1

CMPAL,39H

MOVAL,DL

JBEHTOASC1

CALLHTOASC

ADDAL,7

MOV[BX],AL

HTOASC1:RET

INCBX

HTOASCENDP

LOOPHTASCS12021/5/93

二、主程序与子程序间的参数传递 主程序在调用子程序时,往往要向子程序传递一些参数;同样地,子程序运行后夜经常要把一些结果传会给主程序。主程序和子程序之间的这种信息传递称为参数传递。 有多种参数传递的方法:

(1)寄存器传递法 (2)约定内存单元传递法 (3)堆栈传递法 (4)其它方法

1.利用寄存器传递参数 利用寄存器传递参数就是把参数放在约定的寄存器中。这种方法适用于传递参数较少的情况。2021/5/94

例:写一个大写字母转换为小写字母的子程序

;子程序名:UPTOLW ;功能:大写字母转换为小写字母

;入口参数:AL=字符的ASCII码

;出口参数:AL=字符的ASCII码

;说明:如字符为大写字母,则转换为小写,其它字符不变。

UPTOLWPROC

PUSHF ;保护各标志

CMPAL,‘A’ JBUPTOLW1 CMPAL,‘Z’ JAUPTOLW1 ADDAL,20H UPTOLW1:POPF ;恢复各标志

RET UPTOLWENDP2021/5/95

2.利用约定存储单元传递参数 在传递参数较多的情况下,可利用约定的内存变量来传递参数。 例:写一个实现32位数相加的子程序

;子程序名:MADD ;功能:32位数相加

;入口参数:DATA1和DATA2缓冲区中分别存放要相加的数

;出口参数:DATA3缓冲区存放结果

;说明:

;(1)32位数据的存放次序采用“高高低低”原则

;(2)可能产生的进位放在DATA3开始的第5字节中2021/5/96 MADDPROC

PUSH

AX ;为什么会把AX,CX,SI压入栈?

PUSHCX

PUSHSI MOVCX,2 XORSI,SI ;CF也会被清0 MADD1:MOVAX,WORDPTRDATA1[SI]

ADCAX,WORDPTRDATA2[SI] MOVWORDPTRDATA3[SI],AX INCSI INCSI POPSI LOOPMADD1 POPCX MOVAL,0 POP

AX ADCAL,0 RET MOVBYTEPTR[DATA3+4],AL MADDENDP2021/5/97

3.利用堆栈传递参数 (1)如果利用堆栈传递入口参数,那么主程序在调用子程序之前,把需要传递的参数依次压入堆栈,子程序从堆栈中取入口参数; (2)如果使用堆栈传递出口参数,那么子程序返回前,把需要返回的参数存入堆栈,主程序在堆栈中取出口参数。 例:写一个测量字符串长度的子程序,设字符串以0为结束标志。

;子程序名:STRLEN ;功能:测量字符串长度

;入口参数:字符串起始地址的段值和偏移放在堆栈中

;出口参数:AX=字符串长度。

2021/5/98 STRLENPROC PUSHBP MOVBP,SP PUSHDS PUSHSI MOVDS,[BP+6] MOVSI,[BP+4] MOVAL,0 STRLEN1:CMPAL,[SI] JZSTRLEN2 INCSI JMPSTRLEN1 POPDS STRLEN2:MOVAX,SI POPBP SUBAX,[BP+4] RET POPSI STRLENENDP2021/5/99

主程序调用这个子程序的代码片段如下:

MOVAX,SEGSTR PUSHAX MOVAX,OFFSETSTR PUSHAX CALLSTRLEN MOVLEN,AX

当然,除了上面提及的3种方式外, 如果过程和调用程序在同一文件(同 一程序块中,则过程可直接访问模块 中的变量。2021/5/910

随着指令的丰富、子程序的引入,汇编语言的表达也越来越灵活。为了方便地组织数据,引入了结构伪操作STRUC。

STRUC可以把不同类型的数据放在同一个结构里,方便处理。

a).结构类型说明格式为:

structure_nameSTRUC … ;DB、DW、DD等伪操作

structure_nameENDS

注意:ENDS之前为结构名,注意与段结束相区别。 例如:下列语句说明了一个名STUDENT的结构类型:

STUDENTSTRUC IDDW? SCOREDB0 NAMEDB‘ABCDEFGH’ STUDENTENDS

但是,定义一个结构类型的时候不进行任何存储器分配,只有在定义结构变量时才进行存储分配。2021/5/911 b).结构变量的定义 格式是:[变量名]结构名<[字段值表]>

例:LisiSTUDENT<103,88,‘LI’>;三个字段重新赋值

WangwuSTUDENT<104,,‘WANG’>;字段SCORE仍用缺省值

ZhangsanSTUDENT<>;三个字段均用缺省初值

TeamSTUDENT50DUP(<>);定义50个结构变量,初值不变 在定义结构变量时,如果某个字段有多值,就不能给该字段重新赋初值(定义时存在“DUP”,“,,,”等)。

c).访问方式 访问方式:结构变量名.结构字段名 该变量的地址实质少年宫是结构变量地址的偏移与相应字段偏移值之和。 例:Zhangsan.ID ;访问张三的学号,实际上是直接寻址 还可以把结构变量地址的偏移先存入某个基址或变址寄存器,然后利用“[寄存器名]”来代替结构变量名。 例如:MOVBX,OFFSETZhangsan MOVAL,[BX].SCORE2021/5/912

例:通过结构类型,在主程序和子程序中传输信息。2021/5/913

三、嵌套与递归子程序 一个子程序可以作为调用程序去调用另外一个子程序,这种情况称为子程序的嵌套。 嵌套的层数称为嵌套深度。深度为2的嵌套2021/5/914

如果一个子程序直接调用它自身,这种调用称为(直接)递归调用。 具有递归调用的子程序就称为递归子程序。 递归是嵌套的特殊情况。2021/5/915

递归子程序的设计要点:

(1)递推性:逐级调用; (2)回归性:逐层回归; (3)有穷性:终止条件; 这3点为所有语言递归程序设计具有的共性。 汇编语言设计递归程序时的个性在于:

(1)参数和中间结果一般存于堆栈中,但有时也可以存于寄存器中; (2)递归的深度受堆栈空间的限制。2021/5/916

例:子程序FACT采用递归算法实现阶乘。

;子程序名:FACT ;功能:计算n! ;入口参数:(AX)=n ;出口参数:(AX)=n! ;说明:(1)采用递归算法实现阶乘;

; (2)n不能超过8 FACT(n)=n*FACT(n-1)=n*[(n-1)*FACT(n-2)]…

当n=0时,FACT(0)=1.

要点: (1)递推:只要n不为0,即推进到FACT(n-1); (2)有穷:n=0时有确切解,即FACT(0)=1 (3)回归:逐层返回——FACT(n-1)的解和n(保存的中间参数)2021/5/917 FACTPROC PUSHDX ;保存中间参数(最外层为原有参数)

MOVDX,AX CMPAX,0 ;判断n是否为0?

JZDONE ;如是,则终止推进。(有穷)

DECAX ;否则,继续推进

CALLFACT ;推进

MULDX ;中间结果后逐层返回:n*FACT(n-1) POPDX ;得到中间参数(最外层为原有参数)

RET DONE:MOVAX,1

;给出确定结果0!=1 POPDX ;得到中间参数

RET FACTENDP2021/5/918

四、综合示例 有10个学生的成绩分别为76、69……80。编制一个子程序分别统计60~69分,70~79分,80~89分,90~99分及100分的人数,分别存放到S6,S7,S8,S9,S10单元中。

DSEGSEGMENT

RECDW76,69,63,83,92,73,65,100,99,80

S6DW0

S7DW0

S8DW0

S9DW0

S10DW0 DSEGENDS STACKSEGMENT DW64DUP(?) STACKENDS2021/5/919 CODESEGMENT MAINPROCFAR ASSUMECS:CODE,DS:DSEG,SS:STACK START:PUSHDS

SUBAX,AX

PUSHAX MOVAX,DSEG MOVDS,AX MOVCX,10

CALLCOUNT ;调用COUNT子程序进行统计

;可在此处添加显示输出

RET MAINENDP

注意:红色部分在这里构成一种固定搭配,把主程序看成DOS调用的远过程,RET与前2个PUSH配对,相当于: MOVAH,4CH INT21H2021/5/920 CO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论