第5章 汇编语言程序设计 一. 学习如何运用指令系统中的指令来编制,采用汇编语言程序来学习程序设计。 第5章 汇编语言程序设计 一. 学习如何运用指令系统中的指令来编制,采用汇编语言程序来学习程序设计。 二. 学习如何组织、构造一个汇编语言源程序所必需的各种伪指令的格式、作用和使用。
学习目标 (课时安排:6课时) 一、理解汇编语言程序中3种语句格式、特点和作用。 二、理解汇编语言程序中使用的各种运算符;对常用的运算符(如OFFSET、TYPE、PTR等)应会正确使用。 三、掌握汇编语言程序中符号、数据、段结构和过程的定义方法。 四、掌握汇编语言程序中段寄存器的各种加载方法。
学习目标 五、了解宏指令的定义和使用。 六、掌握无条件转移指令、条件转移指令、循环控制指令、子程序的调用和返回指令的格式与使用。 七、掌握顺序、分支、循环和子程序结构的程序设计方法与技术。 八、理解在数值运算、串操作运算和代码转换中程序设计实例。 九、了解汇编语言程序的开发过程。
§5.1 概述 程序:能完成一定的运算与操作功能的指令序列,称为~。 计算机语言: §5.1 概述 程序:能完成一定的运算与操作功能的指令序列,称为~。 计算机语言: 是以二进制代码0和1组成的机器指令,是计算机能够直接识别和执行的语言。 计算机语言 机器语言 汇编语言 用助记符表示指令功能的计算机语言,它的指令语句与机器指令一一对应。 高级语言 面向用户,与特定机器属性相分离的程序设计语言,更接近人类语言与数学语言。
§5.2 汇编语言语句 汇编语言编制的程序计算机不能识别和执行,必须经过汇编程序的汇编(即翻译)转换成机器语言指令代码(即目标程序),再由计算识别并执行。 语句是汇编语言程序的基本组成单位。 一个汇编语言源程序有3种基本语句: 指令语句 伪指令语句 宏指令语句(或称宏调用语句)
指令语句与伪指令语句 指令语句又称为可执行语句,即每一条指令语句在源程序汇编时都要产生可供计算机执行的指令代码(即目标代码)。 每个语句由4个字段组成: 名字 操作符号 操作数 ;注释 类型 定 义 格式 作用与功能实现方式和时间 指令语句 指令语句又称为可执行语句,即每一条指令语句在源程序汇编时都要产生可供计算机执行的指令代码(即目标代码)。 在目标程序(即指令代码)运行时,依赖于计算机内的CPU、存储器、I/O接口等硬设备来实现的 伪指令语句 伪指令语句又称为命令语句,是指示(命令)汇编程序如何汇编源程序。是由伪指令和相关操作数组成。 同上。 由汇编程序在汇编源程序时,通过执行一段程序来实现的
是指令助记符,表示目标程序在运行时中央处理器CPU应完成的功能。 语句格式:名字 操作符号 操作数 ;注释 1. 名字字段: (1)在指令语句中,名字字段为标号,为一任选字段,且一定是用“:”作为标号的结束符,是一条指令的符号地址通常是一个程序段或子程序的入口指令语句选用标号。 (2)在伪指令语句中,可为常量名、变量名、段名和过程名等,该字段是任选还是必需的,要视伪指令而定。名字字段后面用空格作结束符,不得使用冒号。 (3)组成名字的规则:P174页。 2. 操作符字段: 是指令助记符,表示目标程序在运行时中央处理器CPU应完成的功能。
3. 操作数字段: 是由操作符字段(指令助记符/伪指令)确定。 该字段与操作符字段之间用空格或制表符TAB为分界符。 各操作数之间用逗号或空格分隔。 4. 注释字段: 本字段为任选字段,以分号作这字段的开始符,可由任意字符串表示。 是对某些程序段或指令加以注解,说明它们的功能及意义。
§5.3 汇编语言数据 §5.3.1 符号定义语句 (两种伪指令) §5.3.2 数据定义语句 (1)等值伪指令、 (2)等号伪指令 §5.3 汇编语言数据 §5.3.1 符号定义语句 (两种伪指令) (1)等值伪指令、 (2)等号伪指令 §5.3.2 数据定义语句 (1)数值表达式、 (2)?表达式、 (3)字符串表达式、(4)带DUP表达式
§5.3 汇编语言数据 §5.3.3 数据 §5.3.4 运算符(5种) (1)常数、 (2)寄存器操作数、 (3)存储器操作数 §5.3 汇编语言数据 §5.3.3 数据 (1)常数、 (2)寄存器操作数、 (3)存储器操作数 §5.3.4 运算符(5种) (1)算术运算符、(2)逻辑运算符、 (3)关系运算符、(4)数值返回运算符、 (5)属性运算符、(6)运算符优先级
§5.3.1 符号定义语句 1 . 等值伪指令: 符号 EQU 表达式/符号 格式: §5.3.1 符号定义语句 1 . 等值伪指令: 格式: 功能:EQU是等值伪指令,它把右边<表达式/符号>的值或符号赋给EQU左边的符号。 注意: 等值伪指令语句仅在汇编源程序时,作为替代符号作用,不产生任何目标代码,也不分配存储单元。 在同一源程序中,同一符号不能用EQU伪指令重新定义。 符号 EQU 表达式/符号
<表达式/符号>:见教材以下各例题 (1)常数或数值表达式: 例:COUNT EQU 15*2+10 (2)地址表达式: 例:ADDR1 EQU DS:[BP] (3)变量名、标号或指令助记符 例:NMU1 EQU COUNT1 ; BEING EQU START ; BTOD EQU DAA ; 为变量名CUNT1另定义一个别名。 为标号START另定义一个别名。 为指令助记符DAA另定义一个别名。
§5.3.1 符号定义语句 2. 等号伪指令: 格式: 符号=表达式/符号 功能:与EQU相同 。 等号伪指令与等值伪指令之间的差异: §5.3.1 符号定义语句 2. 等号伪指令: 格式: 符号=表达式/符号 功能:与EQU相同 。 等号伪指令与等值伪指令之间的差异: (1)等号伪指令可以重新定义符号。 (2)等号伪指令可以为已定义的变量名或标号定义另一个别名,但不能为指令助记符定义另一个别名。
§5.3.2 数据定义语句 在存储区中,设置常数、数据或保留若干存储单元,应使用数据定义伪指令: 数据定义伪指令有: DB—定义字节数据 §5.3.2 数据定义语句 在存储区中,设置常数、数据或保留若干存储单元,应使用数据定义伪指令: 数据定义伪指令有: DB—定义字节数据 DW—定义字数据 DD—定义双字数据 DF—定义6字节数据 DQ—定义8字节数据 DT—定义10字节数据
数据定义语句的格式: 变量名 表达式1,表达式2,…… 例: DB DW DD DATA SEGMENT VAR1 DB 12H 变量名 表达式1,表达式2,…… 例: DB DW DD DATA SEGMENT VAR1 DB 12H VAR2 DW 1234H VAR3 DD 12345678H DATA ENDS SEGMENT /ENDS表示逻辑段的开始 / 结束
经过数据定义语句定义的变量,均有3个属性: (1)段属性(SEG):表示变量存放在哪个逻辑段中,且用这个逻辑段的段基值表示。 (2)偏移量属性(OFFSET):表示在逻辑段中离段起始单元(段基址)的距离(字节数)。 (3)类型属性(TYPE):表示变量的数据的大小(字节数据、字数据、双字数据),主要依据DB、DW、DD等伪指令来确定的。
几种表达式: 数值表达式: 例: 2. ?表达式: DA__B1 DB 50 DA__B2 DB 12H,34H,56H 2. ?表达式: DA__B1 DB 50 DA__B2 DB 12H,34H,56H DA__W1 DW 1234H DA__W2 DW 1234H,5678H,9ABCH ?——表示可预置任意内容。?表达式常用于保留一个或多个存储单元,以备程序运行时,作工作单元或保存结果用。 VAR__B DB ?, ? VAR__W DW ?, ?
3. 字符串表达式: (1)字符串必须用引号(单引号或双引号)括起来。 (2)字符串中各字符均是以ASCII码形式存放在相应存储单元中。 (3)DB、DW、DD中的字符串的表示形式和字符ASCII码的存储顺序的差异。具体见教材P177页,及图5—2。
4. 带DUP表达式: 变量名 表达式1 DUP(表达式2) 例: DB DW DD NU__B1 DB 10H DUP(?) 定义重复数据操作符。 4. 带DUP表达式: 变量名 表达式1 DUP(表达式2) 例: DB DW DD 是数据的重复的次数。 是重复数据的内容。 NU__B1 DB 10H DUP(?) NU__W1 DW 20H DUP(10H) ;保留10H个字节单元,每个字节单元可预置任意内容。 ;保留20H个字节单元,每个字节单元预置数据为10H,共占有40H 个字节存储单元。
数据有数值和属性,两部分,对一个语句汇编成机器目标代码有直接关系。 §5.3.3 数据 数据有数值和属性,两部分,对一个语句汇编成机器目标代码有直接关系。 一、常数: 1.数值常数: 2.字符常数: 用单引号或双引号括起来的一个或多个字符组成的字符序列,称为字符常数。 是没有任何属性的纯数值。 二进制数 10111B 十进制数 982D 八进制数 21B、73Q 十六进制数 7AE6H
常数的应用: (1)在指令语句的源操作数中作立即数操作数。 例: (2)在指令语句的寻找存储器操作数的各种寻址方式中作位移量。 (3)在某些伪指令语句的操作数字段中,赋值数据。 例:见教材P179 MOV AL,0ABH MOV BX,‘AB’ MOV AL,DS:[140H] ;直接寻址方式 MOV BX,45H[SI] ;变址寻址方式 MOV 0FEH[BP],AL ;基址寻址方式 MOV 1234H[BH][DI],AX ;基址变址寻址方式
二、寄存器操作数: 1.CPU中通用寄存器和段寄存器的内容可作操作数使用。 2.CS仅可作源操作数,其他寄存器均可。 3.指令指针IP不可作寄存器操作数使用. 4.寄存器的内容作操作数的数据时,用寄存器名表示. 5.寄存器作地址指针时,要将寄存器名用方括号括起来.
指存储单元中的内容,变量、标号及地址表达式是这种操作数的主要表示形式。 三、存储器操作数: 1. 变量: 在一个逻辑段中,用数据定义语句定义并预置数据初值后,变量名就作为存储单元的符号地址,代表了存放在存储单元的数据。 使用变量的两种情况: (1)在指令语句中的操作数字段中,变量名作为址表达式的组成部分之一。 (2)在用DW或DD的数据定义语句中,有三种情况,见教材 P181。
2. 标号: 定义:指令语句的名字字段上的名字,称为标号。是一条指令的符号地址。 标号常作为转移类指令的操作数,表示转移的目标地址。 标号的3个属性: (1)段属性(SEG):表示标号所在指令的逻辑段,且用该逻辑段的段基值表示。 (2)偏移量属性(OFFSET):表示标号所在指令距离起始单元之间的字节数。 (3)类型属性(TYPE):是作为段内转移不是段间转移的目标地址。有 两种。 NEAR(近):段内转移 FAR (远):段间转移
§5.3.4 运算符 1.算术运算符:(表5-1) 2.逻辑运算符:按位进行运算。 AND、OR、XOR、NOT 3.关系运算符: 具体内容见教材 §5.3.4 运算符 1.算术运算符:(表5-1) 2.逻辑运算符:按位进行运算。 AND、OR、XOR、NOT 3.关系运算符: 用于比较两个表达式值的大小。 当比较关系式成立时,用全1表示“真”; 当比较关系式不成立时,用全0表示“假”。
4.数值返回运算符: 定义:数值返回运算符的运算对象是存储器操作数,即由变量名或标号组成的地址表达式。 格式:<运算符> <地址表达式> (1)SEG和OFFSET运算符: 主要反映存储器操作数的地址部分。 该运算符出现在变量名或标号的前面,返回这个变量名或标号所在段的段基值勤或在段内的偏移量。 例:
TYPE运算符是用数字形式表示变量或标号的类型属性。 (3)LENGTH和SIZE运算符: 反映存储器操作数的某些特征。 (2)TYPE运算符: TYPE运算符是用数字形式表示变量或标号的类型属性。 (3)LENGTH和SIZE运算符: 运算符仅加在变量名的前面,它返回的是数组变量的元素个数( LENGTH )和数组变量所占的总字节数( SIZE )。 运算规则: 变量是用重复操作符DUP定义的,则LENGTH 的运算结果是外层DUP的给定值(即外层重复次数)。若无DUP定义,则结果总是1。 SIZE是LENGTH 和TYPE两个运算结果的乘积。
5.属性运算符PTR: 6.运算符优先级:(表5-5运算符优先级) 定义:PTR是用来临时对存储器操作数的类型进行设定、说明。 格式:<运算符> <地址表达式> 例: 6.运算符优先级:(表5-5运算符优先级) (1)先执行优先级别高的运算符; (2)优先级别相同的运算符,按照从左至右顺序进行; (3)可用圆括号改变运算的顺序。
§5.4 伪指令语句 §5.4.1 段定义语句 重点学习段寄存器的各种加载方式 §5.4.2 过程定义语句 §5.4 伪指令语句 §5.4.1 段定义语句 重点学习段寄存器的各种加载方式 §5.4.2 过程定义语句 §5.4.3 定位语句和位置计数器 §5.3.4 偶地址控制语句 §5.3.5 程序标题语句
§5.4.1 段定义语句 一、段定义伪指令(SEGMENT/ENDS) 定义:用于程序中设置一个段(逻辑段)。 格式: §5.4.1 段定义语句 一、段定义伪指令(SEGMENT/ENDS) 定义:用于程序中设置一个段(逻辑段)。 格式: 段名 SEGMENT [ 定位类型 ][ 组合类型][‘类别名’] 本段语句序列(指令或数据) 段名 ENDS …
(2)PARA(节):表示本段从一个小节的边界开始。段的起始单元最后4位二进制数为0(0H)。 由用户自己设定,在程序中当需要引用或调用某逻辑段时,即用段名表示。 1. 段名: 2. 定位类型: 定义:表示对段的起始边界的要求。 定位类型选项:(4种) (1)PAGE(页):表示本段从一个页的边界开始。段的起始地址一定能被256整除。段的起始单元地址(段基址)的最后8位二进制数为0(00H)。 (2)PARA(节):表示本段从一个小节的边界开始。段的起始单元最后4位二进制数为0(0H)。 (3)WORD(字):表示本段从一个偶字节地址开始。 (4)BYTE(字节):表示本段起始单元可以从任一地址开始。
3 . 组合类型:表示段与段之间的连接与定位。有6种选择: (教材P188页) 4 . 类别名: 注:定义一个逻辑段时,段名是必选项,其他三个参数是任选的,各参数之间用空格分隔。任选是可只选其中1-2个,但是不能改变它们的先后顺序关系。 (1). NONE: (2). PUBLIC (3). COMMON (4). STACK (5). AT (6). MEMORY
指4个段寄存器CS、DS、SS、ES中之一 二、段寻址伪指令(ASSUME) ASSUME伪指令格式: 功能:告诉汇编程序已定义的段与段寄存器之间的对应关系。 ASSUME随时修改或撤除1-4个段寄存器与已定义段之间的关系。 ASSUME 段寄存器名:段名,段寄存名:段名,…… 指4个段寄存器CS、DS、SS、ES中之一 指用SEGMENT/ENDS伪指令语句中给定的段名。 ASSUME ES:NOTHING ;撤消对ES的设置 ASSUME NOTHING ;撤消全部段寄存器的设置
数据定义语句DB定义: 一是VAR1存放在DATA1的逻辑段中,其段基值即为DATA的段基值;二是VAR1为字节数据。三是VAR1的偏移量为0。 例: DATA1 SEGMENT VAR1 DB 12H DATA1 ENDS DATA2 SEGMENT VAR2 DB 34H DATA2 ENDS CODE SEGMENT ASSUME CS:CONE,DS:DATA1,ES:DATA2 START …… MOV AL,VAR1 MOV BL,VAR2 CODE ENDS ASSUME定义:段寄存器CS、DS和ES分别存放CODE段、DATA1段和DATA2段的段基值 … MOV取出存储器操作数VAR2,变量VAR2在DATA2段,其段基值在ES中。 …
三、段寄存器的加载 DS和ES的加载: (1)DS——数据段寄存器。 ES——附加段寄存器。
例: … 代码段CODE中第1、3条是以立即数形式把DATA_DS段和DATA_DS段的段基值分别送给通用寄存器AX。 DATA_DS SEGMENT DA1 DB 12H DATA_DS ENDS DATA_ES SEGMENT DA2 DB 10H DUP(0) DATA_ES ENDS CODE SEGMENT ASSUME CS:CONE,DS:DATA1,ES:DATA2 START: MOV AL,DATA_DS MOV DS,AX MOV AX,DATA_ES MOV ES,AX CODE ENDS 第2、4条把AX中的内容(段基值)分别传送给段寄存器DS、ES。 …
2. SS的加载: SS是堆栈段寄存器,对它加载段寄存器就是设置堆栈。 两种SS的加载方法: (1)自动加载: 在段定义伪指令(SEMENT)的组合类型中选择“STACK”参数,就表明这个段是堆栈段。 (2)用执行程序的办法加载: 在程序运行中要调换另一个堆栈段,这时可用类似于DS和ES的加载办法,对SS和SP进行即时修改。
例: … … STACK2 SEGMENT DW 40H DUP(?) TOP LABEL WORD STACK2 ENDS CODE SEGMENT MOV AL, STACK2 MOV SS,AX MOV SP,OFFSET TOP CODE ENDS … …
3. CS的加载: CS和IP提供当前执行目标代码的段基值和偏移量。 对CS和IP设置、修改的两种途径: (1)用结束伪指令END加载程序的起始地址。 (2)执行程序转移类指令,实现从一个段转移到另一个段时,它的指令功能就是修改CS和IP。
用结束伪指令END加载程序的起始地址。 格式: END 地址表达式 其中:地址表达式是一个已定义的标号或一个本标号加减一个常数。是这个程序执行的第一条指令语句的地址。 例: END 地址表达式 结束伪指令END的作用:一是源程序到此结束,后面的任何语句均被汇编程序略去;二是将地址表达式所确认的存储单元的段基值和偏移量分别自动装入CS和IP中。 … CODE SEGMENT ASSUME CS:CONE,… START: MOV AL,DATA CODE ENDS END START …
§5.4.2 过程定义语句 格式: 注意: (1)定义过程的开始(PROC)和结束(ENDP)使用同一过程名,且过程名不能省略。 §5.4.2 过程定义语句 格式: 注意: (1)定义过程的开始(PROC)和结束(ENDP)使用同一过程名,且过程名不能省略。 (2)过程名即为子程序名,也子程序调用指令(CALL)的目标操作数。 (3)过程名也有3个属性。其中类型分为NEAR和FAR。具体内容见教材P192页。 过程名 PROC [ NEAR / FAR ] RET 过程名 ENDP … …
§5.4.3 定位语句和位置计数 格式: 注意: (1)定义过程的开始(PROC)和结束(ENDP)使用同一过程名,且过程名不能省略。 §5.4.3 定位语句和位置计数 格式: 注意: (1)定义过程的开始(PROC)和结束(ENDP)使用同一过程名,且过程名不能省略。 (2)过程名即为子程序名,也子程序调用指令(CALL)的目标操作数。 (3)过程名也有3个属性。其中类型分为NEAR和FAR。具体内容见教材P192页。 过程名 PROC [ NEAR / FAR ] RET 过程名 ENDP … …
§5.5 宏指令语句 宏汇编程序:能处理宏指令功能的汇编程序。 宏指令的使用过程是:宏定义、宏调用、宏展开。
1. 宏定义 … … 格式: (1)不带参数宏定义: (2)带参数宏定义: 宏指令必须首先进行宏定义。MACRO和ENDM是宏定义的开始和结尾伪指令。 1. 宏定义 格式: (1)不带参数宏定义: (2)带参数宏定义: 宏名 MACRO ENDM 宏名 MACRO ENDM 形参1,形参2…… … … 宏体 宏体
2. 宏调用 格式: (1)不带参数宏调用: 宏名 (2)带参数宏调用: … … … 在宏指令定义后,在源程序的任意位置上可以使用宏指令语句(即宏调用) 2. 宏调用 格式: (1)不带参数宏调用: (2)带参数宏调用: 宏名 宏名 实参1,实参2,…… MULTAX10 MULT10 AX,BA … … …
3. 宏展开 宏展开的定义: ——当宏汇匾程序扫描到宏指令语句(宏调用)时,就把宏定义中宏体的程序段目标代码插入宏指令语句的位置上。
§ 5.6 顺序程序设计 顺序程序是最简单的,也是最常用的程序结构形式。 § 5.6 顺序程序设计 顺序程序是最简单的,也是最常用的程序结构形式。 其特点:程序运行时,完全按照编写的指令顺序执行,且每条指令仅执行一次。 例:5-2见教材P197页。 例:5-3见教材P199页。
程序设计中的流程图 流程图中的几个框图符号组成: A 开 始 条件 结 束 A 开 始 条件 结 束 A (a)处理框 (b)判别框 (c)起止框 (d)连接框(e)流向框
例:P73,图3-8(无符号整数一位乘算法流程框图) 开 始 n位被除数—B n位乘数—C,0—A N Y C0=1? A+0—A A+B—A A,C右移一位 N C0=1? Y 结 束
§ 5.7 分支程序设计 § 5.7.1 转移指令 无条件转移指令 条件转移指令 § 5.7.2 分支程序设计 § 5.7 分支程序设计 § 5.7.1 转移指令 无条件转移指令 条件转移指令 § 5.7.2 分支程序设计 直接用条件转移指令实现程序分支 用跳转表实现多路分支
§ 5.7.1 转移指令 一、无条件转移指令: 格式: JMP 目标 功能:使程序无条件地转移到“目标”处。 目标地址的两种表达方式: § 5.7.1 转移指令 一、无条件转移指令: 格式: JMP 目标 功能:使程序无条件地转移到“目标”处。 目标地址的两种表达方式: 1 . 直接寻址方式: 2 . 间接寻址方式:
1 . 直接寻址方式: … … … … … 图5-4 段内转移的直接寻址方式 TARGET2: JMP TARGET2 RD2 RD1 (b)负向转移 正、负向转移都是相对转移,即目标处指令地址与当前JMP指令相对偏移一个位移量。这位移量是以JMP指令的下一条指令与目标处指令之间相距字节数来计算。若目标处指令地址高于J MP指令地址,称为正向转移,反之亦反。
… … CODE1 SEGENT 图5-5 段间转移的直接寻址方式 CODE1 SEGENT TARGET1 LABEL FAR … JMP FAR PTR TARGET1 CODE2 ENDS CODE1 SEGENT TARGET1 LABEL FAR TARGET: CODE1 ENDS … … … … … 段间转移,执行JMP指令时,就把目标处指令地址的段基值和偏移量直接送入CS和IP即可。
2 . 间接寻址方式: 在执行段内转移的JMP指令时,就把存放在通用寄存器或字单元中的偏移量送入IP中,CS不变,实现段的程序转移。 例:JMP CX JMP WORD PTR[BX] JMP [BX] 在执行段间转移的JMP指令时,把存放在双字单元中前2个字节单元的偏移量送入IP,后2个字节单元的段基值送CS,实现间的程序转移。 例:JMP DWORD PTR[BX]
二、条件转移指令: Intel 8086/8088指令系统中条件转移指令共有18条。 格式: J×× 目标 这18条指令都是以标志位寄存器中某一个或几个标志位作为判断条件。 条件转移指令只能是段内转移,也是相对转移。 条件转移指令的种类: (具体内容见教材P203页) 简单条件转移指令 无符号数条件转移指令 带符号数条件转移指令
§ 5.7.2 分支程序 一、直接用条件转移指令实现程序分支 例5-4:编写一程序段,实现表达式运算。 分支程序的结构的两种形式,见教材P204,图5-6 § 5.7.2 分支程序 一、直接用条件转移指令实现程序分支 例5-4:编写一程序段,实现表达式运算。 例5-5:编制一程序,实现两存储区之间的数据传送。 二、用跳表实现多路分支 构造跳转表可用分支程序段的入口地址组成,也可用若干无条件转移指令组成。 例5-6:由入口地址组成跳转表的多路分支程序设计。 例5-7:由转移指令组成跳转表的从路分支程序设计。
§ 5.8 循环程序设计 § 5.8.1 循环控制指令 LOOP指令、LOOPE/LOOPZ指令 § 5.8 循环程序设计 采用循环程序结构实现需要反复执行一段程序才能实现的功能。 § 5.8.1 循环控制指令 LOOP指令、LOOPE/LOOPZ指令 LOOPNE/LOOPNZ指令、JCXZ指令 § 5.8.2 循环程序的结构及循环控制方法 循环程序的结构 循环控制方法 § 5.8.3 单重循环程序设计 § 5.8.4 多重循环程序设计
§ 5.8.1 循环控制指令 4条循环控制指令: 循环控制指令是程序转移类指令,也是相对转移。 § 5.8.1 循环控制指令 采用循环程序结构实现需要反复执行一段程序才能实现的功能。 4条循环控制指令: 循环控制指令是程序转移类指令,也是相对转移。 相对位移量是8位二进制以补码形式表示的带符号整数,即循环控制指令的下一条指令与目标指令之间的字节距离为-128~+127 4条循环控制指令都有隐含使用寄存器CX。 LOOP指令 LOOPE/LOOPZ指令 LOOPNE/LOOPNZ指令 JCXZ指令
1、LOOP指令 格式: LOOP 目标 功能:指令先进行循环次数计数 (即CX (CX)-1),然后判断循环是否结束。如(CX ≠0 ),则转移到目标处,继续循环,否则顺序执行下一条指令。 例5—8:编制一程序,产生n个数的裴波纳契数列。(具体内容见教材P212页)
2、LOOPE/LOOPZ指令 格式: LOOPE 目标 或 LOOPZ 目标 功能:指令先进行循环次数计数 (即CX (CX)-1),然后判断循环是否结束。如(CX ≠0 )且ZF=1,则转移到目标处,继续循环,否则(即(CX)=0或ZF=0)顺序执行下一条指令。 例5—9:(具体内容见教材P214页)
3、LOOPNE/LOOPNZ指令 格式: LOOPNE 目标 或 LOOPNZ 目标 功能:指令先进行循环次数计数 (即CX (CX)-1),然后判断循环是否结束。如(CX ≠0 )且ZF=0,则转移到目标处,继续循环,否则(即(CX)=0或ZF=1)顺序执行下一条指令。 例5—10:(具体内容见教材P215页)
4、JCXZ指令 格式: JCXZ 目标 功能:指令先测试CX的内容,如(CX)=0,则转移到目标处,否则顺序执行下一条指令。
§ 5.8.2 循环程序的结构 及循环控制方法 一、循环程序的结构: 初始化部分 工作部分 修改部分 控制部分 结束处理部分 § 5.8.2 循环程序的结构 及循环控制方法 一、循环程序的结构: 初始化部分 工作部分 修改部分 控制部分 结束处理部分 二、循环控制方法 计数控制循环 条件控制循环
§ 5.8.3 单重循环程序设计 § 5.8.4 多重循环程序设计 单重循环程序的主要特点:循环体由顺序结构或分支结构的一段程序构成。 § 5.8.3 单重循环程序设计 单重循环程序的主要特点:循环体由顺序结构或分支结构的一段程序构成。 例5—11/12:P219—220页 § 5.8.4 多重循环程序设计 多重循环程序就是循环套循环结构形式的程序 例5—13/14:P222—223页
§ 5.9 子程序设计 § 5.9.1 调用与返回 调用指令(段内直接、段内间接、段间直接) 为缩短目标代码,节省内存空间,把一指令序列构成一个相对独立的程序段,以过程的形式组成子程序。 § 5.9 子程序设计 § 5.9.1 调用与返回 调用指令(段内直接、段内间接、段间直接) 返回指令(段内、段间、带弹出值的返回指令RET n) § 5.9.2 编制子程序的基本要求 § 5.9.3 子程序设计举例 § 5.9.4 系统功能子程序的调用 DOS功能子程序的调用 BIOS功能子程序的调用
§ 5.9.1 调用与返回 一、调用指令: 格式:CALL 过程名/子程序名 § 5.9.1 调用与返回 一、调用指令: 格式:CALL 过程名/子程序名 功能:过程名/子程序名就是子程序入口处的符号地址,执行CALL指令时,首先保留断点地址于堆栈中,然后程序转移到指定的子程序入口地址。 段内直接调用 段内间接调用 段间直接调用 段间间接调用
执行返回指令RET后,便按返回地址转移到调用程序。 二、返回指令: 段内返回 段间返回 带弹出值的返回指令RET n
§ 5.9.2 编制子程序的基本要求 1. 具有一定的通用性 2. 选择适当的参数传递方法 3. 注意保存信息 4. 正确使用堆栈 § 5.9.2 编制子程序的基本要求 1. 具有一定的通用性 2. 选择适当的参数传递方法 3. 注意保存信息 4. 正确使用堆栈 5. 编写清晰的子程序文本
§ 5.9.3 子程序设计举例 1. 用寄存器传递参数 2. 用堆栈传递参数 3. 用地址表传递参数
§ 5.9.4 系统功能子程序的调用 DOS功能子程序的调用 BIOS功能子程序的调用
§ 5.10 实用程序设计示例 § 5.11 汇编语言程序的开发 § 5.10.1 数值运算程序设计示例 § 5.10 实用程序设计示例 § 5.10.1 数值运算程序设计示例 § 5.10.2 串操作程序设计示例 § 5.10.3 代码转换程序设计示例 § 5.11 汇编语言程序的开发