欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    汇编语言程序设计初步.ppt

    • 资源ID:6388966       资源大小:450KB        全文页数:99页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    汇编语言程序设计初步.ppt

    第3章 汇编语言程序设计初步,3.1 系统功能调用3.2 汇编语言源程序的设计的基本步骤3.3 分支结构的汇编语言源程序的编写3.4 循环结构的汇编语言源程序的编写,开 始,3.1 系统功能调用,3.1.1 系统功能调用概述3.1.2 基本I/O调用,返回本章首页,3.1.1 系统功能调用概述,我们在编制汇编源程序时,常常要与外部设备发生关系,如希望能从键盘输入字符或在显示器上显示出程序运行的结果,但由于计算机机种的不同、外部设备型号的差异,控制它们工作的程序也会有差异。如果每次都需要根据自己的工作环境来设计“控制这些外设工作 的程序”,则必须要先弄清楚与之有关的设备、电路、接口等各方面的情况,是一件既复杂,效率又低的事情,并且没有通用性。如果把这些控制过程预先编写成一个一个子,程序,作为操作系统的一部分事先放在系统盘上,用户在需要时只要按规定的格式设置好参数,直接调用这些子程序即可。美国MICROSOFT公司为我们提供的磁盘操作系统(DOS)就具有这种功能,称为“利用操作系统的标准功能调用(简称系统功能调用)”,编号从062H(3.0版),主要分为设备管理(如键盘、显示器、打印机、磁盘等的管理)、文件管理、目录管理及其他功能调用4大类。,系统功能调用的基本方法,采用一条软中断指令INT n。所谓中断,是指当计算机正在执行正常的程序时,计算机系统中的某个部分突然出现某些异常情况或特殊请求,CPU这时就中止(暂停)它正在执行的程序,而转去执行申请中断的那个设备或事件的中断服务程序,执行完这个服务程序后,再自动返回到程序断点执行原来中断了的正常程序。这个过程或这种功能就叫做中断。软中断是以指令方式产生的中断,n是中断类型号,不同的n将转入不同的中断处理程序。系统功能调用是21号软中断。,常用的系统功能调用表:,表3-1 最常用的系统功能调用表,系统功能调用的步骤:,1)将调用参数装入指定的寄存器。2)如需要功能调用号(即欲调用的子程序编号),把它装入寄存器AH。3)如需要子功能调用号,把它装入AL。4)按中断号调用DOS(发出中断指令:INT 21H)。5)检查返回参数是否正确。,3.1.2 基本I/O调用,101H号调用 功能:从标准输入设备上(通常为键盘)读取字符,并在标准输出设备上(通常为显示器)回显。格式:MOV AH 01H INT 21H 说明:输入字符的ASCII码送入AL中,如果读到的字符是Ctrl+C或Ctrl+Break,则结束程序。202H号调用 功能:通过标准输出设备(多为显示器)输出字符。,格式:MOV DL,X;(X为要输出显示的ASCII字符代码)MOV AH,02H INT 21H 说明:DL寄存器中的内容等于要输出字符的ASCII码,在显示输出时检查到的字符是Ctrl+C或Ctrl+Break键的,则结束程序。309H号调用 功能:在标准输出上(通常为显示器)显示一个字符串。字符串要以字符“$”为结束标志。格式:MOV AH 09H INT 21H 说明:要输出显示的字符串的首地址送到DS、DX两个寄存器中,其中段地址送DS寄存器,,偏移地址送DX寄存器。40AH号调用 功能:从标准输入设备上(通常为键盘)读一个字符串,存入内存,直到按回车键为止。格式:MOV AH,0AH INT 21H 说明:此项操作,要求事先定义一个输入缓冲区,它的缓冲区首地址送到DS、DX两个寄存器中,其中段地址送DS寄存器,偏移地址送DX寄存器。,【例3-1】在显示器上显示字符串Welcome to TianHe college!,DATAS SEGMENT;/数据段定义开始 STRING DB Welcome to TianHe college!,0AH,0DH,$;/定义字符串,0AH,0DH表示显示字符串后,光标可自动 回车换行,字符串必须以$结束。DATAS ENDS;/数据段定义结束CODES SEGMENT;/代码段定义开始ASSUME CS:CODES,DS:DATAS,SS:STACKS;/说明段和段寄存器之间的关系START:MOV AX,DATAS;/将数据段的段地址送寄存器AX MOV DS,AX;/将AX内容送DS寄存器,即初始化DS LEA DX,STRING;/将STRING的偏移地址送DX寄存器,MOV AH,9;/字符串显示子功能,9号系统功能调用 INT 21H;/系统调用 MOV AH,4CH;/返回DOS INT 21H;/系统调用CODES ENDS;/代码段定义结束END START,【例3-2】从键盘输入字符串,把它放到缓冲区中存储起来。,DATA SEGMENT MAXLEN DB 100;/定义缓冲区的最大容量 ACLEN DB?;/定义实际读入的字符数 STRING DB 100 DUP(?);/定义接收字符串空间DATA ENDS,CODE SEGMENT MOV AX,DATA MOV DS,AX;/数据段初始化 LEA DX,MAXLEN;/送 MAXLEN的偏移地址到寄存器DX MOV AH,10;/10号系统功能调用 INT 21H;/系统调用CODE ENDS运行程序时,若从键盘输入“Thank you!”(共计10个字符),则输入缓冲区MAXLEN各单元的内容如图3-1所示。,图3-1 存储空间分配示意,3.2 汇编语言源程序的设计的基本步骤,3.2.1 源程序的基本框架3.2.2 汇编语言源程序设计的基本步骤3.2.3 顺序结构的汇编语言源程序的编写,返回本章首页,3.2.1 源程序的基本框架,一个汇编语言源程序由两大部分组成的。其中主要部分就是指令,位于代码段内,代码段可以有好几个。其他部分是为指令服务的,包括数据的准备,存储区域的划分和地址的标注。其他部分由数据段、堆栈段和扩展段组成。也各可以有好几个。段之间的顺序可以随意安排。但通常是其他部分(数据段、堆栈段和扩展段等)在前,代码段在后。虽然可以定义多个段,但由于段首址存放在CPU的寄存器中,所以可以同时使用6个段:代码段(CS)、数据段(DS)、堆栈段(SS)和3个扩展段(ES、FS和GS)。扩展段其实也是数据段,只是段地址在寄存器ES、FS和GS中。程序通过修改段寄存器的值实现段的切换。,一个程序至少包含一个代码段和END指令。其他段的设置由程序的具体功能需要而定。程序较小时,可以不设置堆栈段。操作系统在装载不含堆栈段的程序时,会指定一个段作为堆栈段使用。这样,程序连接时,LINK会产生一条警告信息:WARNING:NO STACK SEGMENT 但不会影响程序的运行,可以忽略它。程序中的段名可以是唯一的,也可以与其它段同名。在同一模块中,如果有两个段同名,则后者被认为是前段的后续,这样,它们就属同一段。当同一模块出现两个同名段时,则后者的可选项属性要么与前者相同,要么不写其属性而选用前者的段属性。,【例3-4】段寄存器与段的对应,方法1:用一个段寄存器对应两个数据段DATA1 SEGMENT;/定义第一个数据段 b1 DB10h;/定义变量DATA1,字节变量DATA1 ENDS;/第一个数据段结束DATA2 SEGMENT;/定义第二个数据段 b1 DB23h;/定义变量DATA2,字节变量DATA2 ENDS;/第二个数据段结束CODE1 SEGMENT;/定义第一个代码段ASSUMECS:CODE1,DS:DATA1;/指定段寄存器START:MOV AX,DATA1;/指令开始,MOV DS,AX;/把数据段DATA1的段首址赋给段寄存器DS,MOV BL,b1;/引用DS来访问DATA1中的变量b1ASSUMEDS:DATA2;/说明DS与DATA2建立联系MOV AX,DATA2;MOV DS,AX;/把数据段DATA2的段值赋给段寄存器DS/实现段的切换MOV AL,b2;/引用DS来访问DATA2中的变量b2 CODE1 ENDS;/代码段CODE1结束END START;/程序结束 在方法1中,因为只使用一个段寄存器DS来对应两个数据段,所以,需要切换DS的对应关系。但我们也可以用段寄存器DS和ES来分别对应段DATA1和DATA2,这样,方法1就可变成方法2。,方法2:用两个段寄存器对应两个数据段DATA1 SEGMENT;/定义第一个数据段 b1 DB10h;/定义变量DATA1,字节变量DATA1 ENDS;/第一个数据段结束DATA2 SEGMENT;/定义第二个数据段 b2 DB23h;/定义变量DATA2,字节变量DATA2 ENDS;/第二个数据段结束CODE1 SEGMENT;/定义第一个代码段ASSUMECS:CODE1,DS:DATA1,ES:DATA2;/指定段寄存器START:MOV AX,DATA1;/指令开始,MOV DS,AX;/把数据段DATA1的段首址赋给段寄存器DS MOV AX,DATA2 MOV ES,AX;/把数据段DATA2的段首址赋给段寄存器ES,MOV BL,b1;/引用DS来访问DATA1中的变量b1 MOV AL,b2;/引用ES来访问DATA2中的变量b2 CODE1 ENDS;/代码段CODE1结束END START;/程序结束我们还可以用“段组”来简化段寄存器的使用,把段DATA1和DATA2组成一个数据段。所以,把方法2再改写成方法3的形式。方法3:用一个段组组成两个数据段GSEG GROUP DATA1,DATA2;/定义段组DATA1 SEGMENT;/定义第一个数据段,b1 DB10h;/定义变量DATA1,字节变量DATA1 ENDS;/第一个数据段结束DATA2 SEGMENT;/定义第二个数据段 b2 DB23h;/定义变量DATA2,字节变量DATA2 ENDS;/第二个数据段结束CODE1 SEGMENT;/定义第一个代码段 ASSUMECS:CODE1,DS:GSEG START:MOV AX,GSEG;/指令开始,MOV DS,AX;/把段组GSEG的段值赋给段寄存器DS MOV BL,b1;/引用DS来访问DATA1中的变量b1 MOV AL,b2;/引用DS来访问DATA2中的变量b2,CODE1 ENDS;/代码段CODE1结束END START;/程序结束,定义段组后,段组内各段所定义的标号和变量,除了与定义它们的段起始点相关外,还与段组的起始点相关。规定如下:如果在ASSUME伪指令中说明段组与段寄存器相对应,那么,有关标号或变量的偏移量就相对于段组起点计算;如果在ASSUME伪指令中说明段组内的某段与段寄存器相对应,那么,有关标号或变量的偏移量就相对于该段的起点。所以,在使用段组后,程序员要谨慎使用ASSUME伪指令,并保证段寄存器的值与段组或段相一致。,3.2.2 汇编语言源程序设计的基本步骤,1.汇编语言源程序的主要基本结构:顺序结构 分支结构 循环结构,2.好程序的要求一个好的程序,首先应该能正常运行,实现预定的功能。还应该满足:结构简明,明白易懂,调试方便,修改容易。执行速度快(程序执行时间短,程序语句行数尽量少)。占用内存空间少。,3.基本步骤分析问题,从中抽象出恰当的数学模型。确定解决问题的合理算法。画出程序流程图,根据算法,细化并找出解决问题的思路和具体方法。确定汇编语言程序的基本框架:各个存储段的定义,存储空间的分配,寄存器的配置,指针和计数器的选择。根据程序流程图确定程序的基本结构,并编写程序。,3.2.3 顺序结构的汇编语言源程序的编写,顺序结构是最简单的程序结构,没有分支,没有循环,程序的执行顺序就是指令的编写顺序,所以,又称直线程序。因此,安排指令的先后次序就显得至关重要。另外,在编程序时,还要妥善保存已得到的处理结果,为后面的进一步处理直接提供前面的处理结果,从而避免不必要的重复操作。,【例3-5】两个64位无符号数相加,分析问题:在8086/8088CPU中,只有8位或16位运算指令,没有32位和64位以上的运算指令。确定算法:要进行64位的加法运算,可以确定算法:利用16位加法指令分别相加4次来实现。画程序流程图:本问题简单,无需画程序流程图。确定汇编语言程序的基本框架:可见,汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义3个变量:两个加数N1、N2,还有一个和数SUM,都是DW类型。和数SUM尚属未知,故应定义一个5个字长(比64位字长富余一点)的缓冲区。因为要加4次,需要一个计数器或指针,可选寄存器BX充当。编写程序,可以想得到,需要MOV、ADD、ADC和INC等指令。具体程序如下:,DATA SEGMENT;/定义数据段 N1 DW1234H,5678H,9ABCH,0DEF0H;/定义字变量N1 N2 DW1971H,0313H,1968H,1123H;/定义字变量N2 SUM DW5DUP(?);/定义缓冲区SUMDATA1 END;/数据段结束CODE SEGMENT;/定义第一个代码段ASSUMECS:CODE,DS:DATA;/指定段寄存器MAIN PROC NEARSTART:MOV AX,DATA;/指令开始,MOV DS,AX;/把数据段的段首址赋给段寄存器DS LEA BX,N1;/将N1的偏移地址送BX MOV AX,BX;/引用DS来访问DATA中的变量N1的最低位,ADD AX,BX8;/最低位字相加,因两个数偏移地址相差8个字节 MOV BX16,AX;/存最低位和。BX16指示SUM的偏移地址 此句也可以写为:MOV SUM,AX INC BX INC BX;/指针指向下一个字 MOV AX,BX;/引用DS来访问DATA中的变量N1的次低位 ADC AX,BX8;/次低位字相加,因两个数偏移地址相差8个字节 MOV BX16,AX;/存次低位和。BX16指示SUM1的偏移 地址,此句也可以写为:MOV SUM1,AX INC BX INC BX;/指针指向下一个字 MOV AX,BX;/引用DS来访问DATA中的变量N1的次高位 ADC AX,BX8;/次高位字相加,因两个数偏移地址相差8个字节,MOV BX16,AX;/存次高位和。BX16指示SUM2的偏移 地址,此句也可以写为:MOV SUM2,AXINC BXINC BX;/指针指向下一个字MOV AX,BX;/引用DS来访问DATA中的变量N1的最高位ADC AX,BX8;/最高位字相加,因两个数偏移地址相差8个字节MOV BX16,AX;/存最高位和。BX16指示SUM3的偏移 地址,此句也可以写为:MOV SUM3,AXMOV AX,0;/对AX清零ADC AX,0;/计算进位MOV BX18,AX;/存进位位MOV AH,4CH;/此句也可写成:MOV AX,4C00HINT 21HMAIN ENDPCODE ENDS;/代码段CODE1结束 END START;/程序结束,【例3-6】两个32位无符号数乘法程序,分析问题:在8086/8088CPU中,只有8位或16位运算指令,没有32位以上的乘法运算指令。确定算法:要进行32位的乘法运算,可以确定算法:利用16位乘法指令做4次乘法,然后把部分积相加来实现。每次的积的低位送AX,高位送DX。如图3-2所示。画程序流程图:程序流程图如图3-3所示。确定汇编语言程序的基本框架:可见,汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义3个变量:两个乘数,还有一个积数,都是DW类型。积数尚属未知,故应定义一个4个字长(积的字长应该是乘数字长的两倍)的缓冲区。因为要乘4次,需要一个计数器或指针,可选寄存器BX充当。另外,本程序为了教学的需要,不采用MOV AH,4CH INT 21H,来返回DOS。而改用“先将程序段前缀的起始地址及数据段DS段首址和偏移地址AX存入堆栈,再用指令RET返回DOS的方法。所以,又定义了100个字节的堆栈段。同时堆栈段又为保存最后的进位位提供了条件。编写程序,可以想得到,需要MOV、MUL、ADD、ADC、PUSH、PUSHF和RET等指令。具体程序如下:,NUME 32bit MULTIPLY;程序名“32位乘法”DATA SEGMENT;数据段定义开始MULNUM DW 0000H,0FFFFH,0000H,0FFFFH,4DUP(?);DATA ENDS;数据段定义结束STACK SEGMENT PARA STACK STACK;堆栈段定义开始 DB 100DUP(?);堆栈段长度为100字节STACK ENDS;堆栈段定义结束CODE SEGMENT;代码段开始 ASSUME CS:CODE,DS:DATA,SS:STACK;指定段寄存器START PROC FAR;,图3-3 程序流程图,BEGIN:PUSH DS;将DS中包含的程序段前缀压栈保存 MOV AX,0;将0送AX,即设置AX的初值为0 PUSH AX;将DS中AX的偏移地址压栈,这三句即保存返回至DOS的段值和IP值。MOV AX,DATA;MOV DS,AX;将数据段首地址送DS LEA BX,MULNUM;将MULNUM的偏移地址送BX,定义了地址指针MULNUM32:MOV AX,BX;被乘数的低16位BAX MOV SI,BX4;乘数的低16位DSI MUL SI;BD,部分积1的低位送AX,部分积1的 高位送DX,MOV BX8,AX;保存部分积1的低位 MOV BX0AH,DX;保存部分积1的高位 MOV AX,BX2;被乘数的高16位AAX,MUL SI;AD,部分积2的低位送AX,部分积2的高 位送DX ADD AX,BX0AH;部分积1的高位部分积2的低位 ADC DX,0;加入部分积1的低位的进位 MOV BX0AH,AX;保存部分积1的高位部分积2的低位 MOV BX0CH,DX;保存部分积2的高位 MOV AX,BX;被乘数的低16位BAX MOV DI,BX6;乘数的高16位CDI MUL DI;BC,部分积3的低位送AX,部分积3的高位送DX ADD AX,BX0AH;部分积1的高位部分积2的低位部分 积3的低位 ADC DX,BX0CH;部分积2的高位部分积3的高位进位 MOV BX0AH,AX;保存部分积1的高位部分积2的低位 部分积3的低位,MOV BX0CH,DX;保存部分积2的高位部分积3的高位进位 PUSHF;将标志寄存器压栈,保存“部分积2的高位部分积3的 高位进位”的进位位 MOV AX,BX+2;被乘数的高16位AAX MUL DI;AC,部分积4的低位送AX,部分积4的高位送DX POPF;弹出堆栈保存的“部分积2的高位部分积3的高位进位”ADC AX,BX+0CH;部分积4的低位部分积2的高位部 分积3的高位进位 ADC DX,0;部分积4的高位进位 MOV BX+0CH,AX;保存“部分积4的低位部分积2的高位 部分积3的高位进位”进位 MOV BX+0EH,DX;保存部分积4的高位进位,RET START ENDP CODE ENDS END BEGIN,3.3 分支结构的汇编语言源程序的编写,3.3.1 条件转移指令3.3.2 汇编语言分支结构程序的编写,返回本章首页,在汇编语言程序设计中,常利用条件转移指令实现程序的分支。指令助记符是随条件变化而变化的,其构成方法是:第一个字母是J,紧接着的字母是标志寄存器的代号P、S、Z、,表示“条件”,条件满足,则转移。例如JZ,表示结果为0,则转移;如果“条件”是否定的,就在已构成的两个字母间加字母N,例如JNZ,表示结果不为0,则转移。条件转移指令只有一个操作数,指出转移的目标地址,并且只能是一个短标号,即转移的偏移地址是8位的。有一个条件转移指令JCXZ,构成方法较特殊,它的转移条件是寄存器CX的内容为0,而不是标志寄存器的某位的标志。所有的条件转移指令都不影响标志位。,3.3.1 条件转移指令,(1)根据单个标志的设置情况的转移指令。共五种10条:1)JZ(或JE);上一步的结果为零(或相等)则转移。格式:JE(或JZ)标号测试条件:ZF=12)JNZ(或JNE);上一步的结果不为零(或不相等)则转移。格式:JNZ(或JNE)标号测试条件:ZF=03)JS;上一步的结果为负,则转移。格式:JS 标号测试条件:SF=1 4)JNS;上一步的结果为正,则转移。,现将所有的条件转移指令列举如下:,格式:JNS 标号测试条件:SF=05)JO;上一步的结果为溢出,则转移。格式:JO 标号测试条件:OF=16)JNO;上一步的结果不为溢出,则转移。格式:JNO 标号测试条件:OF=07)JP(或JPE);上一步的结果的奇偶标志位为1,则转移。格式:JP 标号测试条件:PF=18)JNP(或JPO);上一步的结果的奇偶标志位为0,则转移。格式:JNP(或JPO)标号测试条件:PF=09)JC;上一步有进位或借位,则转移。,格式:JC 标号测试条件:CF=110)JNC;上一步无进位或无借位,则转移。格式:JNC 标号测试条件:CF=0,(2)比较两个无符号数,并根据比较结果的高低转移。,1)JA JNBE(或JNBE)高于,即不低于或等于,则转移。格式:JA(或JNBE)标号测试条件:CF0且ZF=02)JNA(或JBE)不高于,即低于或等于,即则转移。格式:JBE(或JNA)标号测试条件:CF=0或ZF=13)JB(或JNAE,JC)低于,即不高于或等于,或进位为1则转移格式:JB(或JNAE,JC)标号,测试条件:CF=14)JNB(或JAE,JNC)不低于,或高于或等于,或进位为0则转移格式:同上测试条件:CF=0,(3)比较两个带符号数,并根据比较的结果的大小转移。,1)JL(或LNGE)小于,或者不大于且等于,则转移。格式:JL(或JNGE)标号测试条件:SF异或OF=12)JNL(或JGE)不小于,即或者大于或者等于则转移。格式:JNL(或JGE)标号测试条件:SF异或OF=03)JLE(或JNG)小于或等于,即不大于则转移。格式:JLE(或JNG)标号测试条件:(SF异或OF)或ZF=1,4)JNLE(或JG)不小于或等于,即大于则转移。格式:JNLE(或JG)标号测试条件:(SF异或OF)或ZF=0,(4)测试CX的值为0则转移指令,格式:JCXZ 标号测试条件:(CX)=0,3.3.2 汇编语言分支结构程序的编写,在设计分支程序时必须注意以下几点:(1)正确选择分支形成的判定条件和相应的条件转移指令。(2)对每个分支程序的 入口,一定要给出标号,标明不同分支的转向地址。必须保证每条分支都有完整的结果。(3)在检查和调试时必须对所有的分支进行,因为某几条分支正确,不足以说明整个程序是正确的。,分支结构程序的分类:简单的二分支结构程序 多分支结构程序,1.简单的二分支结构设计举例,【例3-7】把a,b两个8位数中较大的数赋值给max。分析问题:这是典型的二分支结构。确定分支的条件是ab吗?确定算法:采用比较转移指令,在汇编语言中用AL来保存中间结果。因为读取寄存器比读取存储器要快,并且,汇编语言指令不允许两个操作数都为存储单元。画程序流程图:画程序流程图,见图3-5。,图3-5 例3-7程序流程图,确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义3个变量:两个数a、b,还有一个最大数max,都是8位数,应选DB 类型,但考虑到执行CMP指令实际上是作减法,可能有借位的情况,故选DW类型。max尚属未知,故应定义一个字长的缓冲区。还要用到寄存器AL。编写程序,可以想得到,需要MOV、CMP等指令。最后要返回DOS。具体程序如下:DATA SEGMENT;/定义数据段 a DW?;/定义字变量a b DW?;/定义字变量b max DW?;/定义字变量maxDATA EDNS;/数据段定义结束CODE SEGMENTASSUME CS:CODE,DS:DATA,START:MOV AX,DATA MOV DS,AX MOV AL,a CMP AL,b;/比较a和b,产生分支 JA EXIT;/如果a b,则跳转到EXIT语句,否则,执行下列语句 MOV AL,b;/送b到寄存器EXIT:MOV max,AL;/送(AL)到存储单元max MOV AH,4CH;INT 21H;/返回DOSCODE ENDS;/代码段结束 END START;/程序结束,2.多分支结构程序设计,多分支结构程序设计比较复杂一些。关键是怎样根据条件对多分支进行判断,确定不同分支程序转移的入口地址。方法有:(1)逻辑分解流程图法 根据逻辑分解流程图,按照判别条件的先后,逐个进行判断和转移。设分支条件为X1,X2,XN,则逻辑分解流程图为3-6所示。,图3-6 逻辑分解流程图,【例3-8】试编写执行符号函数 的程序。,分析问题:由题意可知,这是多分支结构。本题有三个分支:X0、X=0和X0和X=0,各分支均用条件转移指令来实现。确定算法:采用比较转移指令。画程序流程图:画程序流程图,见图3-7。确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:数据段和代码段。数据段中至少定义2个变量:两个数X和Y,由题设为8位数,应选DB类型,但考虑到执行CMP指令实际上是作减法,可能有借位的情况,故选DW类型。假设任意给定的X值存放在XX单元,函数Y的值存放在YY单元。编写程序,可以想得到,需要MOV、CMP和程序转移等指令。,最后要返回DOS。具体程序如下:,DATA SEGMENT;/定义数据段 XX DW;/定义字变量X YY DW?;/定义字变量Y DATA EDNS;/数据段定义结束CODE SEGMENTASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX;/给DS赋值MOV AL,XX;CMP AL,0;/XX与零比较,JGE BIGR;/X(AL)0,则转移到BIGR语句 MOV AL,0FFH;/否则,X0时,将1送入AL EQUL:MOV YY,AL;/无论结果如何,都将(AL)送入YY单元 HLT;/暂停,(2)跳转地址表法,如果各分支的判定结果可以用一个寄存器的不同的有序的值来表示,则可将各分支程序的入口地址与寄存器的不同的有序的值一一对应,列入一张表中,此表称为跳转地址表。,如图3-8所示。各分支程序的入口地址的计算公式是:,各分支程序的入口地址寄存器的值2跳转地址表首地址 这种利用跳转地址表实现多分支程序的转移的方法,称为跳转地址表法。,图3-8 分支程序入口地址表,【例3-9】根据AL中的被置位的情况来控制转移到8个分支程序R1R8中的一个(在中断响应时,通过软件查询,从而转到相应的中断服务程序入口就类似于这种情况)。,如果AL中为00000001 则转至R1如果AL中为00000010 则转至R2如果AL中为00000100 则转至R3如果AL中为00001000 则转至R4如果AL中为00010000 则转至R5如果AL中为00100000 则转至R6如果AL中为01000000 则转至R7如果AL中为10000000 则转至R8实现上述要求的程序框图如图3-9所示。我们可以把8个子程序的入口地址编成如图3-8所示的分支程序入口地址表。根据流程图可以写出如下程序:,分析问题:由题意可知,要求根据某种条件实现8个分支程序确定算法:采用跳转地址表法(见图3-8 分支程序入口地址表),结合条件转移指令来实现。画程序流程图:见图3-9。确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架要三个段:数据段、堆栈段和代码段。数据段中创建分支程序入口地址表,应选DW 类型,使用寄存器BX定位。编写程序,可以想得到,需要MOV、JMP、JC、INC、LEA和PUSH等指令。最后要返回DOS。未想到的,在编写过程中根据需要随时添加,如RCR指令等。具体程序如下:NAME BRANCH_PROGDATA SEGMENT,BRTAB DW R11;/开始创建分支程序入口地址表。第一步创建分支程序R1入口地址的IP值 DW R12;/创建分支程序R1入口地址的码段值 DW R21;/仿DW R11,下同 DW R22;/仿DW R12,下同 DW R31 DW R32 DW R41 DW R42 DW R51 DW R52 DW R61 DW R62 DW R71 DW R72 DW R81 DW R82,图3-9 分支程序转移流程图,DATA ENDSSTACK SEGMENT PARA STACK STACK DB 100 DUP(?);/定义一个100个字节的堆栈空间TOP EQU$-STACK;/栈顶的地址为程序的当前地址与堆栈首地址的差。STACK ENDSCODE SEGHENTSTART PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:PUSH DS;/将数据段首址压栈 MOV AX,0;/将寄存器AX清零 PUSH AX;/使程序能返回DOS MOV AX,DATA MOV DS,AX;/将DATA段首址(即分支程序入口地址表)送寄存器DS,MOV AX,STACK;MOV SS,AX;/将堆栈段首址送寄存器SS MOV AX,TOP MOV SP,AX;/将堆栈段栈顶地址送堆栈指针寄存器SP LEA BX,BRTAB;/设跳转表的地址指针GTBIT:RCR AL,l;/通过进位循环右移 JC GETAD;/在循环右移过程中顺序检查AL中各位的状态 INC BX;/BX自动加1 INC BX;/BX自动加1,移到下一分支 INC BX;/BX自动加1 INC BX;/BX自动加1,完成寄存器的值2 JMP GTBITGETAD:JMP DWORD PTRBX;/段间间接转移START ENDPCODE ENDS END BEGIN,(3)跳转指令表法,跳转指令表法的思路与跳转地址表法基本相同,不同的只是它是在代码段中把转移到各个分支程序段的跳转指令放在一个表中,该表就称为“跳转指令表”。,表内跳转转移指令的地址的计算公式:,表内跳转指令表的地址(编号-1)2+跳转指令表的首地址 编号2-2+跳转指令表的首地址,当 N=1时,显示信息(DSPLAY);N=2时。传送信息(TRAN);N=3时。处理信息(PROCl);N=4时,打印信息(PRTN);N=5时。结束程序(EXIT)相应的处理为一独立的程序段,它们的入口地址分别为DSPLAY,TRAN,PROC l,PRIN,EXIT。当这些程序处理结束时仍返回读入N。只有当N5时程序才结束。试利用跳转指令表的分支程序实现这些要求。,【例3-10】由键盘输入一个数N,当N为不同值时应作不同处理,分析问题:由题意可知,这是一个五分支程序。它们的入口地址分别为DISPLAY,TRAN,PROCl,PRIN,EXIT。当这些程序处理结束时仍返回读入N。只有当N5时程序才结束确定算法:构建跳转指令表,采用通过执行跳转指令表中相应的跳转指令,就可以转移到不同的分支。画程序流程图:略。确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:堆栈段和代码段。堆栈段中定义一个256个字的缓冲区,当然是DW 类型,再定义一个字类型的栈顶,用栈顶指针SP定位。采用寄存器AL,AX存数字,寄存器BX存跳转指令的地址。编写程序,可以想得到,需要MOV、JMP、LEA、SUB、ADD、CMP和JB、JA、CBW等指令。最后要返回DOS。未想到的,在编写过程中根据需要随时添加,如SHL指令等。为了简化程序,每段处理程序除了EXIT以外仅给出了一条转移指令表示当某项处理完成后返回AGAIN继续从键盘读入一个字符直到输入字符为5,为止。例中存放转移指令的表JADT2在代码段中。具体程序如下:STACK SBGMENT STACKDW 256 DUP(?);/在堆栈中,定义一个256个字的数据缓冲区TOP LABEL WORD;/定义栈顶变量TOP,字类型STACK ENDSCODE SEGMENTASSUME CS:CODE,SS:STACKSTART:MOV AX,STACK;MOV SS,AX;/堆栈段寄存器SS初始化 MOV SP,OFFSSET TOP;/送栈顶的偏移地址到寄存器SPAGAIN:MOV AH,01;/(AH)01,1号功能(键盘输入)调用,INT 2lH;/DOS功能调用 SUB AL,30H;/将键盘输入的数字字符的ASCII码减去 数字字符“0”的ASCII码“30H”,求出输入 数字的二进制表示的值,放在AL中 CMP AL,01;/与“1”比较输入数字的值 JB,AGAIN;/若输入数字的值比1小,返回程序AGAIN,由键盘重新输入。若输入数字的值比1大,接 着执行下一指令 CMP AL,05;/与“5”比较输入数字的值 JA AGAIN;/若输入数字的值比5大,返回程序AGAIN,由键盘重新输入。若输入数字的值比1大,比 5小,接着执行下一指令 SHL AL,01;/将放在AL中的输入数字的二进制表示,逻 辑左移1位。依据计算跳转转移指令地址的 公式:先作编号2,CBW;/将AL中的8位数扩展为16位数,放在寄存器AX中MOV BX,OFFSSET JADT2;/送转移指令跳转表的首地址 送寄存器BXADD BX,AX;/依据计算跳转转移指令地址的公式再作:编 号2+跳转指令表的首地址SUB BX,02;/继续计算,将上一步的结果减去2,完成计算 JMP BX;/跳转到BX指示的跳转指令的地址JADT2 JMP SHORT DISPLAY:/跳转表 JMP SHORT TRAN JMP SHORT PROCl JMP SHORT PRTN JMP SHORT EXITDISPLAY:,JMP AGATNTRAN:JMP AGAINPROCl:JMP AGAINPRIN:JMP AGAINEXlT:MOV AH,4CHINT 2lHCODE ENDSEND START,3.4 循环结构的汇编语言源程序的编写,3.4.1 循环控制指令3.4.2 程序的循环结构3.4.3 控制程序循环的方法3.4.4 多重循环,返回本章首页,(1)循环指令的作用:根据条件满足与否,完成一串重复的操作,形成循环程序。(2)循环指令有3条,且3条指令都是短转移(short-label表示短标号)指令。循环转移指令LOOP 格式:LOOP 目标标号测试条件与功能:(CX)不等于0,则(CX)(CX)1;(IP)(IP)8位偏移量。,3.4.1 循环控制指令,说明:LOOP指令相当于下面两条指令的组合:DEC CXJNZ short-label;short-label表示短标号 相等(为零)循环转移指令LOOPZ/LOOPE格式:LOOPZ(或LOOPE)目标标号测试条件与功能:(CX)等于0且ZF=1,则(CX)(CX)1;(IP)(IP)8位偏移量。LOOPNZ/LOOPNE循环指令格式:LOOPNZ(或LOOPNE)目标标号测试条件与功能:(CX)不等于0且ZF=0;则(CX)(CX)1;(IP)(IP)8位偏移量。,【例3-11】将数据区的数据按正、负分开,分别送到两个缓冲区,程序如下:,START:MOV SI,OFFSET BLOCK;/将数据区的偏移地址送 SI,即将 SI指向数据区 MOV DI,OFFSET PLUS-DATA;/DI指向正数缓冲区 MOV BX,OFFSET MINUS-DATA;/BX指向负数缓冲区 MOV CX,COUNT;/将数据字节送CX CLD;/将DF清0GOON:LODSB;/取串指令 TEST AL,80H;/字节最高位为1(表示是负数)吗?JNZ MINUS;/是,则转移到MINUS语句 STOSB;/否则,执行存入串指令STOSB JMP AGAIN;/跳转到AGAIN语句MINUS:XCHG BX,DI;STOSB

    注意事项

    本文(汇编语言程序设计初步.ppt)为本站会员(牧羊曲112)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开