1、第4章 汇编语言程序设计,4.1 汇编语言概述 4.2 汇编语言程序实现 4.3 汇编语言程序设计方法及应用 4.4 汇编语言程序设计举例,汇编语言(Assembly Language)是一种采用指令助记符、符号地址、标号、伪指令等符号编写程序的程序设计语言。用汇编语言编写的程序称为汇编语言源程序(Source Program)。 一般情况下,一个助记符对应一条机器指令,所以汇编语言也是面向机器的语言。,4.1 汇编语言概述,4.1.1源程序的结构与组成,【例题4.1】实现:123 + 456sum 的源程序,CODE SEGMENT ;语句6ASSUME CS:CODE,DS:DATA MA
2、IN PROC FAR ;语句8 START:PUSH DS ;语句9. ;RET ;语句17 MAIN ENDP ;语句18 CODE ENDS ;语句19,数据段,代码段,DATA SEGMENT ;语句1A DW 123 ;语句2B DW 456 ;语句3SUM DW ? ;语句4 DATA ENDS ;语句5,END START ;语句20,名字 指令/伪指令 操作数1,操作数2,段=语句,1. 源程序组成,源程序=段,段,一个汇编语言源程序中,代码段是不可缺少的,其它段(数据段、堆栈堆、附加段)视具体情况而定。 该程序共有2个段:行1行5为一段、行6行19为一段DATA、CODE分别
3、为2个段的名字。每一段有明显的起始语句与结束语句,这些语句称为“段定义”语句。代码段的第一个语句ASSUME(本例中行7),用于明确段与段寄存器的关系。本程序中DATA是数据段、CODE是代码段。,段:数据段、堆栈段、附加段、代码段,语 句,源程序由语句组成。汇编语言源程序语句可以分为:,指令语句伪指令语句宏指令语句,语句:指令性语句,由CPU执行,如:语句8语句17。指示性语句,指示汇编,如语句1、5、6、19、20。,名字:段 名,如:DATA、CODE变量名,如:A、B、SUM过程名,如:MAIN标号名,如:START,名 字,汇编语言源程序中的变量名、标号、常量名、段名、宏名等统称为“
4、名字”。,段 名,如:DATA、CODE变量名,如:A、B、SUM过程名,如:MAIN标号名,如:START,1) 组成名字的合法字符有: 字母(不分大小写); 数字09; 特殊符号(“?”,“:”,“”,“_”,“$”)。 2)名字以字母开头。 3)不能把保留字用作名字。,(1).名字命名规则,(2).名字属性,1)变量名,2)段名:该段起始位置的段地址值,段属性:变量所代表的数据区所在段的段基址 ; 偏移量:变量所代表的数据区首字节所在段内偏移地址 ; 类 型:BYTE、WORD、DWORD、DQ、DT 长 度:变量所代表的数据区中数据元素的个数。 规 模:变量所代表的数据区中数据所占空间
5、大小,以字节计。,3)过程名 或标号名,4)常量名:代表一常数,段属性:过程起始位置或标号处段地址值 偏移量:过程起始位置或标号处偏移地址值 类 型:NEAR、FAR,用于程序跳转,4.1.2 汇编语言伪指令,1.数据定义伪指令变量名 数据定义伪指令 操作数1,操作数2,DB、 DW 、 DD 、 DQ、 DT,字节、字、双字、4字、5字的变量。,(1) 数字常量:十进制、八进制、十六进制、二进制等,缺省形式是十进制; (2) 字符常量,用单引号括起来,被存储的是该字符的ASCII码; (3) 符号常量,必须是预先已定义的符号; (4) 符号“?”,表示预留空间,内容不定; (5) DUP,表
6、示内容重复的数据。具体形式为:次数 DUP(被重复的内容),操作数:,【例】D_A DB 10, A, BCD_B DW 1234HD_C DQ 5678H,D_A 0AH41H 42H43HD_B 34H12HD_C 78H56H0 0 000 D_C+7 0,(1)DB定义的数据,每个数据元素占据1个存储单元;DW定义的数据,每个数据元素占据2个存储单元; (2)字数据存储时,低字节存储在低地址单元中,高字节存储在高地址单元中; (3)字符被存放时为它的ASCII码,例 A的ASCII码为41H; (4)符号地址具有以下关系:D_B = D_A+3D_D = D_B+2 = D_A+6,注
7、:,ORG 100HD_E DB 3 DUP(?)EVEND_F DW D_ED_G DB 2 DUP(1,3,4)D_H DW $+2,变量 内容 偏移地址 D_E ? 100? 101? 102103 D_F 00H 10401H 105 D_G 1 1063 1074 1081 1093 10A4 10B D_H 0EH 10C01H 10D,下一个存储位置从偶地址开始,己定义变量,取该变量偏 移地址,代表当前偏移地址,2.符号定义伪指令,(1) EQU 格式:名字 EQU 表达式,例:VB EQU 641024 ;VB代表数值表达式的值A EQU 7B EQU A2,注意:1. 如果表
8、达式中有变量,应在该语句前给出该变量的定义;2. EQU语句不能给某一变量重复定义;3. VB、A、B不占用内存,(2)等号=,格式:名字 = 表达式,功能:与EQU基本相同,区别是它可以对同一个名字重新定义。 例:COUNT = 10MOV AL,COUNT ;COUNT = 5 ;可重复定义,例: ABC DW ?A1 EQU BYTE PTR ABC ;A1是ABC的第一个字节A2 EQU BYTE PTR ABC1 或 A2 EQU A11MOV AL,A1MOV AH,A2,例,可以如下处置: MOV AX,WORD PTR OPER1+1 ; AX=3402H MOV AL, BY
9、TE PTR OPER2 ; AL=34HMOV AL, BYTE PTR OPER2+1 ; AL=12H,(3)LABEL,格式:变量/标号 LABEL 类型,功能:定义变量或标号的类型,而变量或标号的段属性和偏移属性由该语句所处的位置确定。,变量的类型有:BYTE、WORD、DWORD、 DQ、DT;标号的类型有:NEAR、FAR。,【例】利用LABEL使同一个数据区有一个以上的类型及相关属性。 AREAW LABEL WORD ;AREAW与AREAB指向相同的数据区,AREAW类型为字,而AREAB类型为字节 AREAB DB 100 DUP(?) MOV AX,1234H MOV
10、AREAW,AX ;(AREAW) = 1234H MOV BL,AREAB ;BL = 34H,3.段定义伪指令,段名 SEGMENT 定位类型 组合类型 类别 段名 ENDS,BYTE: B,即段可以从任何地址开始; WORD: 0B,即段的起始地址必须为偶地址; PARA: 0000B,即段从节(PARAGRAPH)边界开始,每16个字节为1小段,所以,其起始地址必为16的倍数。 PAGE: 0000 0000B,即段从页边界开始,每256个字节为1页,所以,其起始地址必为256的倍数。,*定位类型:说明段的起始地址应有怎样的边界值:,*组合类型:说明程序连接时的段合并方法,1 PUBL
11、IC:将同类别名段组装在一起形成一个逻辑段; 2 STACK: 与PUBLIC一样,只用于堆栈段。在汇编及连接后,系统自动为SS及SP分配值,在可执行程序中,SP初值指向栈底。 3 COMMON:同名段从同一个内存地址开始装入。所以,各个逻辑段将发生覆盖。连接以后,该段长度取决于同名段中最长的那个,而内容有效的是最后装入的那个。,4 MEMORY:与PUBLIC同义,只不过MEMORY定义的段装在所有同名段的最后。若连接时出现多个MEMORY,则最先遇到的段按组合类型MEMORY处理,其他段组合类型按PUBLIC处理。 5 PRIVATE:不组合,该段与其它段逻辑上不发生关系,即使同名,各段拥
12、有各自的段基值。缺省值 6 AT exp:段地址为表达式exp的值(长度为16位)。此项不能用于代码段。,当几个程序模块进行连接时,其中具有相同类别名的段,按出现的先后顺序被装入连续的内存区。没有类别名的段,与其它无类别名的段一起连续装入内存。,类别:类别的作用是在连接时决定各逻辑段的装入顺序。类别名必须用单引号括起来。,ASSUME 段寄存器名:段名,段寄存器名:段名,ASSUME:用于明确段与段寄存器的关系,说明: 该伪指令出现在码段中; 本伪指令只是指示各逻辑段使用段寄存器的情况,并没有对段寄存器的内容进行赋值。DS、ES的值必须在程序段中用指令语句进行赋值,而CS、SS由系统负责设置,
13、程序中也可对SS 进行赋值,但不允许对CS赋值。,例:ASSUME DS:DSEG,CS:CSEG,ES:ESEG,SS:SESG,例:ASSUME CS:CODE,DS:DATA,ES:DATA,*【例】按下面要求,写出程序框架,数据段从0E000H开始,其中有100字节的数组,其类型属性既是字又是字节; 2. 堆栈段从小段开始,段组名为STACK; 3. 代码段中指定段寄存器,主程序从1000H开始,给有关段寄存器赋值; 4. 程序结束。,DSEG SEGMENT AT 0E000HD_BYTE DB 100 DUP(?)D_WORD EQU WORD PTR D_BYTE DSEG EN
14、DS SSEG SEGMENT PARA STACKDB 200 DUP(?) SSEG ENDS CSEG SEGMENT ORG 1000HASSUME CS:CSEG,DS:DSEG,SS:SSEG,MAIN PROC FARXOR AX,AXPUSH AXPUSH DSMOV AX,DSEGMOV DS,AXRETMAIN ENDP CSEG ENDSEND MAIN,4. 模块定义和结束伪指令, NAME 格式:NAME 模块名 功能:为源程序的目标程序指定一个模块名。如果程序中没有NAME伪指令,则汇编程序将TITLE伪指令定义的标题名前6个字符作为模块名;如果程序中既没有NAME
15、,又没有TITLE,则汇编程序将源程序的文件名作为目标程序的模块名。,格式:END 标号 功能:表示源程序的结束。标号指示程序开始执行的起始地址。如果多个程序模块相连接,则只有主程序要使用标号,其它子模块只用END而不必指定标号。, END,5、其它伪指令, 对准伪指令EVEN 格式:EVEN 功能:使下一个分配地址为偶地址。 说明:在8086中,一个字的地址最好为偶地址。因为8086 CPU同样的存取一个字,如果地址是偶地址,需要一个读或写周期,如果是奇地址,需要2个读或写周期。所以,该伪指令常用于字定义语句之前。,格式:ORG 表达式 表达式取值范围为:065535,无符号数 功能:指定其
16、后的程序段或数据块所存放的起始地址的偏移量。, 定位伪指令ORG,格式:RADIX 表达式 表达式取值为216内任何整数。 功能:指定汇编程序使用的默认数制。缺省为十进制。,【例】MOV BX,0FFH ;十六进制数要加后缀MOV BX,178 ;十进制数不要加后缀RADIX 16 ;设置16进制为默认数制MOV AX,0FF ;十六进制数不要加后缀MOV BX,178D ;十进制数要加后缀, 基数控制伪指令RADIX,4.1.3 汇编语句与运算符,1 、语句格式:名字 操作 操作数 ;注释,常量、变量和表达式组成,由常量、变量和运算符组成,2、运算符,例 1)ARRAY DW 1*2+3-4
17、,56HMOV AX,ARRAY ;汇编后为:MOV AX,12)MOV AL,7FH MOD 2 ;汇编后为:MOV AL,13)MOV AH,15/4 ;汇编后为:MOV AH,3,(1)算术运算符,(2)逻辑运算符,例1: MOV AH,11110000B MOV AL,NOT AH ;MOV AL,00001111B MOV BL,AH OR AL ;MOV BL,11111111B MOV BH,AH XOR AL ;MOV BH,11111111B,例2:从端口86H读取一个字节,高位屏蔽后从端口6送出。PORT EQU 86HIN AL,PORTAND1 AL,0FH ;AND1
18、为逻辑指令MOV DX,PORT AND2 0FH ;AND2为汇编运算符OUT DX,AL,(3)关系运算符,关系运算符两边的操作数必须是两个数值或同一段中两个存储单元地址,运算结果应为逻辑值,结果为真,表示为0FFFFH;结果为假,则表示为0。,例:A EQU 80HB EQU 88HMOV AL,A EQ BMOV AH,A NE BMOV BL,A LT BMOV BH,A GT B MOV CL,A LE BMOV CH,A GE B,(4)分析/数值返回运算符,SEG 变量或标号,返回变量或标号的段地址,OFFSET 变量或标号,返回变量或标号的偏移量,TYPE 变量或标号,LEN
19、GTH 变量,SIZE 变量,返回变量或标号的类型值,返回DUP定义的数据占据的单元数; 非DUP定义的数据,返回1。,返回DUP定义的数据占据的字节数; 非DUP定义的数据,返回类型值。,变量类型值:DB:1,DW:2,DD:4,DQ:8,DT:10。 标号类型值:NEAR:-1,FAR:-2。,【例】数据定义如下: DATA SEGMENT AT 2000HBUF1 DB 0,1,2,3,4,5,6,7,8,9BUF2 DW 5 DUP(0) DATA ENDS 则: SEG BUF1 = 2000H SEG BUF2 = 2000H OFFSET BUF1 = 0000H OFFSET
20、BUF2 = 000AH TYPE BUF1 = 1 TYPE BUF2 = 2 LENGTH BUF1 = 1 LENGTH BUF2 = 5 SIZE BUF1 = 1 SIZE BUF2 = 10,(5)属性运算符,属性运算符用来建立或改变已定义变量、内存操作数或标号的类型属性。属性运算符有:PTR、THIS、SHORT,1)PTR,类型 PTR 变量 / 标号,典型应用之一:重新指定变量类型 例:数据定义如下:BUFW DW 1234H,5678H则下列指令合法:MOV AX,BUFW;临时改变BUFW的字属性为字节属性MOV AL,BYTE PTR BUFW,典型应用之二:指定内存操
21、作数的类型 例:INC BX ;汇编将指示出错INC BYTE PTR BX ;正确INC WORD PTR BXSI ;正确,分析:在寄存器间接寻址、寄存器相对寻址、基址变址寻址或相对基址变址寻址等内存寻址方式中,往往很难判断出操作数的类型属性,应对操作数类型加以说明。,典型应用之三:与EQU一起定义一个新的变量变量或标号 EQU 类型 PTR,例: BUFW DW 1234H,5678H BUFB EQU BYTE PTR BUFW ;BUFB的类型属性为字节,其它属性与BUFW一样。 MOV AX,BUFW ;AX=1234H MOV AL,BUFB ;AL=34H,2)THIS,格式:
22、THIS 类型可以像PTR一样建立一个指定类型的地址操作数,该操作数的段地址和偏移地址与下一个存储单元地址相同。,例: BUFB EQU THIS BYTE BUFW DW 1234H,5678H . MOV AX,BUFW ;AX=1234H MOV BL,BUFB ;BL=34H,BUFB的偏移地址和BUFW完全相同,但它是字节类型;而BUFW则是字类型。,3) SHORT,格 式: SHORT 标号 返回值:偏移量在-128+127范围内的标号。 说 明:用于JMP指令。即: JMP SHORT 标号,指明是短转移。,4) 其它,字节分离运算符HIGH、LOW 格 式:HIGH 表达式L
23、OW 表达式 返回值:表达式值的高字节或低字节 【例】CONST EQU 0ABCDHMOV AH,HIGH CONST ;AH = 0ABHMOV CL,LOW CONST ;CL = 0CDH,运算符的优先级,3. 注释项,注释项用来说明一段程序或一条或几条指令的功能,此项为可选项,不会影响程序的执行。好的注释,使程序容易读懂、便于维护。对编程者而言,注释项是一种“备忘录”。写注释时,要注意注释不仅是对指令自身功能的说明,而更应从整体上说明该语句或一组语句所起的作用。,在循环程序的开始都有初始化程序,设置有关工作单元的初值:MOV CX,100 ;将100送入CXMOV SI,0100H
24、;将0100送入SIMOV DI,0200H ;将0200送入DI 这样注释没有说明它们在程序中的真正作用,应改为:MOV CX,100 ;循环计数器CX置初值MOV SI,0100H ;源数据区指针SI置初值MOV DI,0200H ;目标数据区指针DI置初值,例,多个模块之间的参数传送: 局部符号:在本模块中定义,在本模块中引用的符号 外部符号:在某一模块中定义,在另一模块中引用的符号PUBLIC 符号 EXTRN 符号:类型,*、 PUBLIC 与 EXTRN,例:,; proadd1.asmextrn proadd : far data segment commonary dw 1,2
25、,3,4,5,6,7,8,9,10count dw 10sum dw ? data ends code1 segment main proc farassume cs:code1, ds:data start:mov ax, datamov ds, axcall far ptr proaddmov ah, 4chint 21h main endp code1 endsend start,; proadd2.asmpublic proadd data segment commonary dw 1,2,3,4,5,6,7,8,9,10count dw 10sum dw ? data ends co
26、de2 segment proadd proc farassume cs:code2,ds:datamov ax, datamov ds, axpush axpush cxpush silea si, arymov cx, countxor ax, ax,next: add ax, siadd si, 2loop nextmov sum,axpop sipop cxpop axret proadd endp code2 endsend,4.2 汇编语言程序实现,汇编程序返回DOS方法,1.标准方法MAIN PROC FARPUSH DSMOV AX,0PUSH AXRETMAIN ENDP,2
27、.DOS功能调用方法MOV AH,4CHINT 21H,4.3.1 概述 4.3.2 顺序结构程序设计 4.3.3 分支结构程序设计 4.3.4 循环结构程序设计 4.3.5 子程序设计 4.3.6* 宏定义与使用 4.3.7 系统功能调用,4.3 汇编语言程序设计方法及应用,(1)分析问题包括找出已知条件、问题特点、问题中的规律并归纳出数学模型。注意:有些问题不一定非要写出数学模型,或者根本写不出数学模型。但是,当有了一个数学模型之后,就可使用很多行之有效的计算方法。 (2)确定算法指根据人们在解决实际问题时的逻辑思维中的常规推理,去找算法。如果已有数学模型,可以直接或间接利用一些现有的计算
28、方法。,1.程序设计步骤,4.3.1 概述,(3) 绘制流程图,采用流程图: (1)使解题思路清淅,有利于理解和编制程序; (2)有利于修改程序和减少错误等; (3)对于一个复杂的问题,可以画多级流程图,先画出粗框图,再逐步求精,画出细框图。,流程图是程序算法的图形描述,即用图形的方式把解决问题的先后次序和程序的逻辑结构直观地、形象地描述出来;,(4)分配存储空间及工作单元(包括寄存器),8088/8086存储器结构要求存储空间分段使用。因此,数据段、堆栈段、代码段以及附加段要按需要分别定义。工作单元即可以设置在数据段或附加段中的某些存储单元,也可以设置在CPU内部的数据寄存器中。,根据流程图
29、和确定的算法逐条语句地编写程序,注意不同的机器有不同的指令系统。,(5)编写程序,(6)静态检查,看程序是否具有所要求的功能; 程序是否清晰易读; 选用指令是否合适; 程序语法和格式上是否有错; 指令中引用的符号、标号和变量是否定义正确; 程序执行流程是否符合算法和流程图等等; 适当考虑字节数要少,执行速度要快等。,(7)运行调试,静态检查可以发现一些问题,但毕竟还受到个人主观因素的影响。只有在机上运行通过并且结论正确的程序,才是正确的程序。事实上,即使一个非常有经验的程序员,也不能说程序一编就成功,特别是一些复杂的程序,必须经过调试、修改、再调试、再修改,反复多次之后,才能得到一个比较满意的
30、程序。,【例】编程实现在100个无符号字节整数的数组中找出最大数。,(1)分析问题本例中,有100个整数的数组,可以把它看作一个集合,记作S。在此集合中找出最大数,记为maxS。 (2)确定解决问题的算法人工方法:首先从第一个数据开始,一边看一边比较两个数的大小,看到较大数就记下,将较小数丢掉;再将此较大数与下一个数进行比较,始终将比较大的数记下,一直将数组中的数两两比较完毕,就能找到最大数。,首先,建立一个数据指针指向数据区的首地址,将第一个数取到某个寄存器中(例AL),与下一个数相比较,若下一个数大,就将它存到AL中,替换掉原来的数;然后调整数据指针,将AL的数与此指针所指的数进行比较,再
31、重复上述步骤,两两比较下去,直到比较完毕,结果AL中留下最大数。,(3)算法、流程图,Y,N,N,Y,(4)存储设计及数据定义,把数组存放在数据段中,并设置50个字节堆栈空间。利用BX寄存器作数据指针,用CX作计数器,用AL暂存较大数。,DSEG SEGMENT ;定义数据段ARRAY DB X1,X2 COUNT DW $-ARRAY ;计算数据个数 DSEG ENDS SSEG SEGMENT PARA STACK STACK ;定义堆栈段SDAT DB 50 DUP(?)TOP EQU LENGTH SDAT SSEG ENDS,CSEG SEGMENT ;定义代码段ASSUME CS:
32、CSEG,DS:DSEG,SS:SSEGMAIN PROC FAR ;定义过程START:PUSH DS ;为返回DOS作准备MOV AX,0PUSH AXMOV AX,DSEGMOV DS,AX ;设置DSMOV AX,SSEG MOV SS,AX ;设置SSMOV AX,TOPMOV SP,AX ;设置SP初值 MOV BX,OFFSET ARRAY ;设置数据区指针首地址,MOV CX,COUNT ;设置计数器初值DEC CX ;设置比较次数MOV AL,BX ;取数入AL AGAIN:INC BX ;指向数据区下一个数据CMP AL,BX ;两数比较JAE NEXT ;ALBX,转NE
33、XTMOV AL,BX ;否则,把较大数取入ALNEXT: DEC CX ;全部数据比较完否?JNZ AGAIN ;否,转AGAINRET ;全部比较完毕,返回DOSMAIN ENDP CSEG ENDSEND START,汇编语言的基本结构:,2. 结构化程序设计,4.3.2 顺序结构程序设计,顺序结构,顺序结构程序又称简单程序。这种结构的程序中无程序跳转指令、无循环指令,所有指令按其书写顺序逐条顺序执行,程序的执行路径从上到下只有一条。因此,顺序程序的设计只要依照步骤写出相应的指令即可。,【例题4.3】将存储单元A中2个压缩BCD数拆成2个非压缩的BCD码,低位BCD数存入C中,高位BCD
34、数存于B中,并将对应的ASCII码存入C1及B1中。,分析:将1个字节中的两位BCD码分开,即分别取出其高4位和低4位。得到低位BCD码的方法是:屏蔽高4位、保留低4位。得到高位BCD码的方法是:逻辑右移4位,左边移入4个0。由未组合的BCD码转为ASCII码,只要加30H或“OR 30H”。,DATA SEGMENT ;数据定义A DB 37H ;被转换数B DB ? ;安排结果保存空间C DB ?B1 DB ? ;保存中间结果C1 DB ? ;保存中间结果 DATA ENDS,流程图及编码,CODE SEGMENTASSUME CS:CODE,DS:DATAMAIN PROC FARSTA
35、RT: PUSH DSMOV AX ,0PUSH AX ;保存返回地址MOV AX,DATAMOV DS,AX ;设置DS,MOV AL,A ;取出高位BDC码MOV CL,4SHR AL,CL MOV B,AL OR AL,30H ;高4位,转换成ASCII码MOV B1,AL ;保存高4位的转换结果MOV AL,A ;取出低位BCD码AND AL,0FHMOV C,ALOR AL,30H ;低位BCD码,转换成ASCII码MOV C1,AL ;保存低4位的转换结果RET ;返回DOS MAIN ENDP CODE ENDSEND START,P97:阅读下面程序,指出运行结果 DATA S
36、EGMENT BLOCK DW 0ABCDH BUFF DD ? DAT ENDS CODE SEGMENTASSUME CS: CODE, DS:DATASTART: MOV AX , DATAMOV DS, AXMOV DX, BLOCKMOV AX, DXAND AX, 0F0FHAND DX, 0F0F0HMOV CL, 4SHR DX, CLLEA BX, BUFMOV BX+0, ALMOV BX+1, DLMOV BX+2, AHMOV BX+3, DHMOV AX, 4C00HINT 21H CODE ENDSEND START,4.3.3 分支程序设计,分支程序结构:,跳转的
37、实现,在8088/8086 指令系统中,判断的依据主要是运算结果及运算标志寄存器中的状态位。实现跳转的指令是无条件跳转指令:JMP label与条件跳转指令:Jcc short-label,双分支程序,双分支程序有以下五个部分组成: 产生条件的语句:如算术运算指令、比较指令、移位指令等,通过它们影响标志寄存器状态位ZF、CF、OF、SF等,为条件测试作准备。 条件测试语句:利用条件转移指令进行测试。 定向:根据判断的条件,决定程序的不同走向,在两种可能转移方向中选择其一。 顺序控制图:无论选择哪个方向,都必须保证执行分支段程序后,程序顺序执行下去。 标号:在分支程序段前设置标号,以便于转移。,
38、程序段1,条件测试,分支1,分支2,Y,N,S2,BRANCH,图 4.11 双分支程序组成,【例题4.4】比较两个无符号字节数,把大数存入MAX单元。,CSEG SEGMENTASSUME CS:CSEG,DS:DSEGSTART: MOV AX,DSEG ;给数据段地址附值MOV DS,AXMOV AL,NUMBER ;取第一个数CMP AL,NUMBER+1 ;与第二个数JNC BRANCH ;若第一个数第二个数,转BRANCHMOV AL,NUMBER+1 ;否则,第二个数大 BRANCH: MOV MAX,AL ;保存较大数MOV AH,4CHINT 21H CSEG ENDS EN
39、D START ;汇编结束,DSEG SEGMENTNUMBER DB 32h,54h MAX DB ? DSEG ENDS,数据定义,码 段,多分支程序设计,多分支结构中,条件有多个。这些条件之间存在两种情况:一是所有条件中只可能有一个条件成立,称为“相异性条件”;二是所有条件中可能有两个以上甚至所有条件都成立,称“相容性条件”。对于相异性条件,要保证各个条件所对应的分支程序段互斥执行,即对特定的输入,只能选择分支程序中的一个运行。 对于相容性条件,注意条件判定的次序,一旦找到成立的条件后,就执行相应的程序段,其后的条件是否成立,就不进行判断了。,多分支程序设计方法,设计多分支程序的关键是如
40、何按条件对多分支进行判断,从而根据不同的条件,转移到不同的入口去执行。常用方法有三种:转移表法地址表法逻辑分解法。, 转移表法,转移表法也称为跳转表法,其设计思想是:把转移到各分支的转移指令预先依次存放在一张表中,此表称为“跳转表”,如图4.13所示;分支选择时,先计算实现该分支的跳转指令在跳转表中的地址x;然后通过一个JMP x指令,跳转到该处,实现分支选择,如图4.14所示。,跳转表,【例题4.5】 设一监控程序,有10个编号分别为09控制命令键,如启动、执行、复位等,按下任一命令键相当于发出一条键盘命令,而这些命令功能的实现由10个子程序完成,这些子程序的入口地址为ADR0ADR9。,采
41、用转移表法,首先将JMP ADR0 JMP ADR9的10条跳转到10个子程序的指令存于跳转表中。如果按键号为X,因每条跳转指令长度为3个字节,则按键X对应的命令子程序的跳转命令在跳转表中的偏移量是3X。,设X已送入寄存器AL,由X实现转向相应命令子程序的程序如下: MOV AH,0 MOV BL,AL ADD AL,AL ;求2X ADD AL,BL ;求3X,即位移量 MOV BX,OFFSET BRA_TAB ;设BRA_TAB为表首 ADD BX,AX JMP BX, 地址表法,如果把上述跳转表中的跳转指令换成各分支程序的入口地址,即为地址表。 地址表法指:多分支跳转时通过采用间接寻址
42、方式,从地址表中找到分支入口地址实现分支选择。,【例题4.6】 某工厂有8种产品的加工程序R0R7分别存放在以ADR0ADR7为首地址的内存区域,这8个首地址连续存放在以BASE为首地址的地址表内,如图所示。,从图知: 偏移量=产品编号2 表地址=表基地址+偏移量,根据产品编号,选择加工程序的部分代码如下:,DSEG SEGMENT BASE DW ADR0,ADR1,ADR2,ADR3,ADR4,ADR5,ADR6,ADR7 ;地址表 BN DW ? ;产品编号 DSEG ENDS CSEG SEGMENTMOV SI,BN ;取产品编号ADD SI,SI ;计算偏移量MOV BX,BASE
43、SI ;计算表地址JMP BX ;分支跳转RET START ENDP CSEG ENDSEND BEGIN, 逻辑分解法,逻辑分解法的思路是将多分支结构按条件的先后依次分解成一串双分支结构,然后使用双分支的实现方法进行程序设计。此方法多用于相容性条件的多分支程序。,【例题4.7】 若寄存器AL中存放了当前外部中断请求的情况。AL中的每一位D7D0对应一个中断源的中断请求,共8个INT7INT0。若有中断请求INTi,对应位Di为1;无中断请求,对应位为0,并设某一刻系统只能响应一个中断请求。由于系统中可能会同时出现多个中断请求(即AL中同时有多位为1),因此必须对中断请求设置优先级。假定优先
44、级顺序与数据位低到高的顺序一致,即D0上中断请求最高,D7上中断请求最低,处理流程如图所示。,在进行条件测试时,通过对寄存器AL移位,依次检测各位,程序为:, ROR AL,1 ;取D0位 JC R0 ;检测D0位 ROR AL,1 ;取D1位 JC R1 ;检测D1位 ROR AL,1 ;取D2位 JC R2 ;检测D2位 ROR AL,1 ;取D7位 JC R7 ;检测D7位 ,【例】编程实现下列函数的功能,其中X、Y为无符号字节数。(多分支),流程图,(AL)=(BL)?,PUSH DS SUB AX, AX PUSH AX MOV AX, DAT MOV DS, AX,CMP AL,
45、BL JE C1 JA C2,EXT: MOV Z, ALRET,MOV AL, X MOV BL, Y,C1:MOV AL, 0JMP EXT,C2:MOV AL, 1JMP EXT,MOV AL, -1,CMP AL, BLJE C1 JA C2MOV AL, -1JMP EXTC2: MOV AL, 1JMP EXTC1: MOV AL, 0EXT: MOV Z, ALRET Main endp CSEG ENDS END STARTSk41.asm,DATA SEGMENT X DB 56h Y DB 88H Z DB ? DATA ENDS CSEG SEGMENT ASSUME C
46、S:CSEG,DS:DATA Main proc far START:PUSH DSSUB AX, AXPUSH AXMOV AX, DATA MOV DS, AXMOV AL, X MOV BL, Y,4.3.4 循环结构程序设计,(1)初始化部分这是循环的准备部分,为程序操作、地址指针、循环计数、结束条件等设置初始值。 (2)循环体,包括以下3个部分:循环工作部分-这是循环程序的主体,完成程序的基本操作,循环多少次,这部分语句就执行多少次。循环修改部分-修改循环工作部分的变量地址等,这保证每次重复时,参加执行的数据能发生有规律的变化。循环控制部分-保证循环条件满足时进入循环;循环结束条件不满足时,退出循环,执行循环体外的后续语句。 (3)循环结束部分完成循环结束后的处理,如数据分析、结果的存放等。,循环程序典型结构,零次或先判断后执行,先判断循环条件是否满足。当循环条件满足时,执行循环体;当循环条件不满足时,执行结束部分。这种结构的循环,有可能循环体一次也得不到执行,非零次或先执行后判断,循环体至少执行一次后,才判别循环条件,循环程序典型结构,(1) 先执行后判断,