《微机原理第3章汇编语言及编程.ppt》由会员分享,可在线阅读,更多相关《微机原理第3章汇编语言及编程.ppt(89页珍藏版)》请在三一文库上搜索。
1、3-1,第三章 汇编语言及编程,3.1 汇编语言程序结构与汇编语句 3.2 伪指令语句 3.3 汇编语言编程环境 3.4 DOS/BIOS功能调用 3.5 三种基本结构程序的设计 3.6 子程序设计与调用,3-2,3.1 汇编语言程序结构与汇编语句,3.1.1 汇编语言源程序结构 3.1.2 汇编语言的语句,3-3,3.1.1 汇编语言源程序结构,80X86/Pentium系列MPU汇编语言都是以逻辑段为基础,按段的概念来组织代码和数据的。因此,源程序结构与逻辑段的定义方法密切相关,而宏汇编语言MASM 5.0以上的版本中,逻辑段既可用完整段定义,又可用简化段定义。,3-4,1. 标准的单模块
2、源程序框架,.586 DATA SEGMENT USE16/USE32 ;定义数据段 ;数据定义伪指令序列 DATA ENDS STACK SEGMENT USE16/USE32 STACK ;定义堆栈段 ;数据定义伪指令序列 STACK ENDS CODE SEGMENT USE16/USE32 ;定义代码段 ASSUME CS:CODE,SS:STACK,DS:DATA,ES:DATA START: MOV AX,DATA ;取数据段基址 MOV DS,AX ;建立DS的可寻址性 MOV ES,AX ;建立ES段的可寻址性 ;核心程序段 MOV AH,4CH ;返回DOS操作系统 INT
3、21H CODE ENDS END START, 一个源程序由若干逻辑段组成。一般一个源程序具有数据段、附加数据段、堆栈段和代码段;但只有代码段是必不可少的。,3.1.1 汇编语言源程序结构,3-5,3.1.1 汇编语言源程序结构,(1) 使用DOS的4CH号功能调用 这种方法是在代码段结束前加调用语句: MOV AH,4CH ;功能号4CHAH INT 21H ;中断调用,(2) 使用20H号软功能调用 调用方式是在代码段结束前加调用语句: INT 20H,(3) 使用DOS的0号功能调用 调用方式是在代码段结束前加调用语句: MOV AH,0 INT 21H,2.返回DOS状态的方法,3-
4、6,(4) 将主程序定义为远过程,也称为“标准序”方法。这种方法是在代码段开始处按下述方式定义主程序: CODE SEGMENT ASSUME 主过程名 PROC FAR PUSH DS SUB AX,AX ;标准序 PUSH AX RET 主过程名 ENDP END 主过程名,3.1.1 汇编语言源程序结构,3-7,指令语句 伪指令语句 宏指令语句,3.1.2 汇编语言的语句,语句是汇编语言程序的基本组成单位,用于规定汇编语言的一个基本操作。汇编语言包含三种基本语句:,是可执行语句,由硬件(CPU)完成其功能,汇编时产生目标代码 。,不可执行语句,其功能由相应软件完成,不产生目标代码。,用户
5、定义的新指令,汇编时产生相应的目标代码。,3-8,标号和名字分别是给指令单元和伪指令起的符号名称,统称为标识符。(注意组成的语法规则) 助记符和定义符分别用于规定指令语句的操作性质和伪指令语句的伪操作功能,统称操作符。 操作数操作数允许有多个,这时各操作数之间要用逗号“,”隔开。,3.1.2 汇编语言的语句,指令语句: 标号: 助记符 操作数 ;注释 伪指令语句: 名字 定义符 操作数 ;注释,1. 语句格式,3-9,2. 数 据,汇编语言中使用的数据有常数、变量和标号。,(1) 常数 常数是指那些在汇编过程中已有确定数值的量,分为数值常数和字符串常数两类。主要用作:,指令语句中的立即操作数
6、基址、变址或基址加变址寻址中的位移量 伪指令语句中用于给变量赋初值,3.1.2 汇编语言的语句,3-10,标号是指令的符号化地址,一定在代码段,而变量是数据的符号化地址,一般在数据段,有时也可在代码段定义。,变量与标号有三个共同属性:,段基址:所在段的起始地址(SEG) 偏移值:相对于段基址的位移量(OFFSET) 类型:所占存储单元的字节数(TYPE)/NEAR和FAR,(2) 变量与标号,3.1.2 汇编语言的语句,3-11,变量与标号区别,标号可以用作转移控制类指令的操作数,但变量不能。 变量可以用作基址、变址或基址加变址寻址的位移量,但标号不能。,3.1.2 汇编语言的语句,3-12,
7、例3.1 假设VAR1和VAR2为字变量,LAB为程序中的一个标号,判断下列指令是否正确,若错误请指出错误之处:, ADD VAR1,VAR2 SUB AL,VAR1 JNZ VAR1 JMP LABSI JMP NEAR LAB MOV AX,VAR1BX JMP VAR2BX,错,不允许存储器变量间直接传数,错,源与目的操作数类型不一致,错,变量不能用作条件转移指令的操作数,错,标号不能用作变址寻址的位移量,错,缺PTR运算符,正确,正确,3.1.2 汇编语言的语句,3-13,3. 表达式,表达式是汇编语句操作数的基本形式,由运算符和运算对象组成。,3.1.2 汇编语言的语句,3-14,指
8、在汇编过程中能够由汇编程序计算出数值的表达式。可作为指令中的立即操作数和数据区中的初值使用。例如: MOV BX,0FFF0H AND 0B234H MOV AL,4CH EQ 2 MOV AH,4CH GT 1 MOV AX,SEG LABLE,表达式又分为数值表达式和地址表达式:,3.1.2 汇编语言的语句,数值表达式,3-15,其值表示存储器地址,一般都是段内的偏移地址。与变量一样,地址表达式也具有段值、偏移值和类型属性。地址表达式主要用来表示指令语句中的操作数,例如: MOV AX,BASEEAXEBX JMP BASEEAX LEA BX,BASE+12,3.1.2 汇编语言的语句,
9、地址表达式,3-16,3.2.1 程序结构伪指令语句 3.2.2 符号定义伪指令 3.2.3 数据定义伪指令 3.2.4 过程与宏定义伪指令 3.2.5 结构定义伪指令,3.2 伪指令语句,3-17,3.2.1 程序结构伪指令语句,方式选择伪指令 完整段定义伪指令 指定地址伪指令 模块定义伪指令,这类语句是与程序结构紧密相关的基本伪指令语句,用于说明CPU的类型、逻辑段结构、源程序(或模块)起止信息和段内存的安排等。主要包括:,3-18,1. 方式选择伪指令,方式选择伪指令用于通知汇编程序,当前的源程序指令是哪一种CPU指令,经过汇编链接之后生成的目标程序在哪一种CPU机型上运行。不属于选定C
10、PU的指令均为非法指令。所以,方式选择伪指令本质上也就是指令集选择伪指令。 通常,方式选择伪指令放在程序的头部,作为源程序的第一条语句。缺省时默认8086指令集。,3.2.1 程序结构伪指令语句,3-19,2. 完整段定义伪指令,采用完整段定义伪指令可具体控制汇编程序(MASM)和链接程序(LINK)在内存中组织代码和数据的方式。 主要包括段定义语句和段寄存器说明语句。,3.2.1 程序结构伪指令语句,3-20,3.2.1 程序结构伪指令语句, 段定义语句, 格式: 段名 SEGMENT 定位类型,组合类型,字长选择,类别 段体 ;由指令、伪指令和宏指令语句组成 段名 ENDS, 说明: (1
11、) SEGMENT/ENDS是一对段定义语句,一个逻辑段从SEGMENT语句开始,到ENDS语句结束。,(2) 段名是用户定义的段的标识符,用于指明段的基址。,(3) 4个可选参数用于为源程序的汇编、连接提供必要的信息,特别是模块化程序,各个模块如何定位,彼此之间如何连接,将较多地涉及到定位类型和组合类型的选择。,3-21, 组合连接举例:,模块2(从模块): DSEG SEGMENT COMMON ARRAY_B DW 200 DUP(?) DSEG ENDS SSEG SEGMENT STACK DW 50 DUP(?) SSEG ENDS CSEG SEGMENT PUBLIC CSEG
12、 ENDS END,模块1(主模块): DSEG SEGMENT COMMON ARRAY_A DW 100 DUP(?) DSEG ENDS SSEG SEGMENT STACK DW 50 DUP(?) SSEG ENDS CSEG SEGMENT PUBLIC ASSUME CS:CSEG,DS:DSEG,SS:SSEG START: MOV AX,DSEG MOV DS,AX CSEG ENDS END START,3.2.1 程序结构伪指令语句,3-22, 段寄存器说明语句,格式: ASSUME 段寄存器:段名,段寄存器:段名,,功能: 说明源程序中定义的段由那个段寄存器去寻址。,说
13、明: CS只能用于包含有程序的段,反之含有程序的段也只能以CS作为段寄存器。SS也一样,只能与堆栈段对应。, CS所对应的段名必须在该语句之前有定义。, 该语句是说明性语句。,3.2.1 程序结构伪指令语句,3-23,3. 指定地址伪指令,格式: ORG 偏移地址 ORG $ + 偏移地址 功能: 该伪指令以其指定的偏移地址或由$ 给出的当前地址加上指定的偏移地址作为当前开始分配和使用的偏移地址。,3.2.1 程序结构伪指令语句,3-24,4. 模块定义伪指令,模块定义伪指令包括模块开始和模块结束语句。 (1) 模块开始语句(NAME) 格式:NAME 模块名 功能:指示源程序开始,并指出该源
14、程序的模块名。 (2) 模块结束语句(END) 格式:END 标号/过程名 功能:模块结束语句表示源程序到此结束。,3.2.1 程序结构伪指令语句,3-25,3.2.2 符号定义伪指令,格式:,赋值语句:符号名 EQU 表达式,功能: 都是用符号名代替表达式的值。但赋值语句定义的符号名不能重新定义,而等号语句允许。,1. 符号常数定义伪指令,等号语句:符号名 = 表达式,3-26,例3.2 赋值语句与等号语句举例。 赋值语句: X EQU 50 Y EQU X +10 COUNT EQU $ - ARRY 等号语句: CON = 5 BASE = 200H BASE = BASE + 10H
15、;重新定义BASE,3.2.2 符号定义伪指令,3-27,2. 定义符号名伪指令,格式: 符号名 LABEL 类型,功能:将紧跟在本伪指令后的标号、操作码、过程或变量建立新的符号名,并刷新其类型,但它并不为新指定的变量或标号分配存储空间。,例如: SUB_FAR LABEL FAR ;远调用入口 SUB_NEAR: MOV AL,SI ;近调用入口,两个标号SUB_FAR和SUB_NEAR均指向同一条指令,前者为远标号,后者为近标号。,3.2.2 符号定义伪指令,3-28,3.2.3 数据定义伪指令,功能: 是为数据项或项表分配存储空间,给它们赋初值,并用一个符号名(称为变量)与之相联系。,3
16、-29,使用说明:, 给变量赋初值可以是赋确定的值,也可以是赋不确定的值(用“?”表示),还可以是用DUP运算符建立的多次拷贝。,例3.3 使用80X86汇编语言的伪操作命令定义: VAL DB 93 DUP(5,2 DUP(2 DUP(1,2 DUP(3),4) 则在VAL存储区内前10个字节单元的数据是 ?,解:由内向外逐层展开,分别相当于: 93 DUP(5,2 DUP(2 DUP(1,3,3),4) 93 DUP(5,2 DUP(1,3,3,1,3,3,4) 93 DUP(5,1,3,3,1,3,3,4,1,3,3,1,3,3,4) 即表示重复93个数据序列: 5,1,3,3,1,3,
17、3,4,1,3,3,1,3,3,4,3.2.3 数据定义伪指令,3-30, 使用SEG、OFFSET、TYPE、LENGTH和SIZE运算符求变量的各种属性时,特别要注意:,对LENGTH运算符,如果变量是用重复数据操作符DUP说明的,则返回外层DUP给定的值;如果没有DUP说明,则返回值总是1。 对SIZE运算符有:SIZE =TYPELENGTH,使用说明:,3.2.3 数据定义伪指令,3-31,解: 此题有两层DUP定义,但最外层DUP给定的值为100,所以: (BX)= 数组ARRAY的偏移地址; (CX)= 数组ARRAY的长度 = 100; (SI)= 数组ARRAY的类型 = 2
18、。,例3.4 若数组ARRAY在数据段中已作如下定义: ARRAY DW 100 DUP(123H,3 DUP(?),1234H 试指出下列指令执行后,有关寄存器的内容是多少?,MOV BX,OFFSET ARRAY MOV CX,LENGTH ARRAY MOV SI,0 ADD SI,TYPE ARRAY,3.2.3 数据定义伪指令,3-32, 操作符“$”是取地址计数器的当前值,常用于表达式定义数组长度。,例3.5 已知: ORG 0100H ARY DW 3,$+4,5,6 CNT EQU $ - ARY DB 7,8,CNT,9 下列指令执行后, AX、BX寄存器的值为多少? MOV
19、 AX,ARY+2 MOV BX,ARY+10,解:画出数组ARY的内存分配图。,(AX)=ARY+2=0102H =0106H (BX)=ARY+10=010AH=0908H,使用说明:,3.2.3 数据定义伪指令,3-33, 使用DB、DW、DD定义串数据(用 定义的字符串)时,允许定义的串长度不同,字符的存放顺序也不相同:,DB是从左至右顺序为每个字符分配一个字节单元; DW是从左至右顺序为每2 个字符分配一个字单元,且前面的字符在高字节,串长度不能超过2; DD是从左至右顺序为每4 个字符分配一个双字单元,也是按前面的字符在高字节顺序存放,串长度不能超过4。,3.2.3 数据定义伪指令
20、,3-34,例3.6 今需在变量名为STRING的数据区中顺次存放数据A、B、C、D、E、F、G、H,请写出分别用汇编命令DB、DW和DD实现的语句。,解:用DB、DW和DD实现的语句分别为: STRING DB ABCDEFGH STRING DW BA,DC,FE,HG STRING DD DCBA,HGFE,3.2.3 数据定义伪指令,3-35,3.2.4 过程与宏定义伪指令,过程定义伪指令 宏定义伪指令 宏和过程的比较,3-36,格式:过程名 PROC 属性 ;过程体 RET RET 过程名 ENDP,说明:, 过程允许嵌套调用,还可以递归调用。, 过程与逻辑段也可以相互嵌套,但决不允
21、许过程与段交叉覆盖。,过程又称为子程序。它是一段必须通过CALL指令调用才能执行的程序段,执行完后通过一条RET指令返回原调用处。过程需先定义才能调用。, 过程体中必须至少包含一条RET指令,这是过程的出口。但也允许过程有多条RET指令,即过程有多个出口。,1.过程定义伪指令,3.2.4 过程与宏定义伪指令,3-37,宏定义格式: 宏名 MACRO 形式参数表 ;宏体 ENDM,说明:宏定义的宏名必须唯一,称为宏指令。宏指令一经定义就可以在源程序的任何地方调用。相当于由用户给汇编程序提供了一个新的操作码。,宏调用格式: 宏名 实际参数表,3.2.4 过程与宏定义伪指令,宏的概念与过程很相似,也
22、是用一个宏名字来代替源程序中经常要用到的一个程序模块。,2. 宏定义伪指令,3-38,3.2.4 过程与宏定义伪指令,使用宏定义和宏调用时要注意两个问题:, 对带参数的宏指令,宏调用时实际参数与形式参数的类型要一致,以免产生无效调用 。, 宏调用是用宏体中定义的指令序列替换宏指令,所以宏体内的标号要用LOCAL伪指令说明为局部标号,以免多次调用宏时,发生标号重复定义错误。,LOCAL伪指令格式: LOCAL 标号1,标号2,,3-39,解:宏定义如下: MOVE MACRO SARY,DARY LOCAL LP MOV SI,0 MOV CX,100 LP: MOV AL,SARYSI MOV
23、 DARYSI,AL INC SI LOOP LP ENDM,例3.7 定义宏MOVE,其功能是将一个有100个字节元素的数组搬移到另一个数据区。,进行宏调用: MOVE FIRST,SECOND 宏展开如下: MOV SI,0 MOV CX,100 ?0000:MOV AL,FIRSTSI MOV SECONDSI,AL INC SI LOOP ?0000,3.2.4 过程与宏定义伪指令,3-40,3. 宏和过程的比较,宏和过程都可简化源程序的书写,因而也减少了程序出错的可能性。但两者使用上也有区别:,3.2.4 过程与宏定义伪指令,(1) 宏操作可以直接传递和接收参数,而过程不能直接带参数
24、。当过程之间需要传递参数时,必须通过堆栈、寄存器或存储器来进行,编程比宏要复杂。,所以,宏汇编适合于代码较短,传送参数较多的子功能段使用,子程序适合于代码较长,调用比较频繁的子功能段使用。,(3) 引入宏操作并不会在执行目标代码时增加额外的时间开销,但过程调用由于要保护和恢复现场及断点,因此会延长目标程序的执行时间。,(2) 子程序不管被调用多少次它都只被汇编一次,即有唯一的一段目标代码;而宏指令则调用多少次就汇编多少次,每次调用都要在程序中展开并保留宏体中的每一行。,3-41,3.2.5 结构定义伪指令,在一些应用中,常需要将一些不同类型的数据组合成一个有机整体。这时就要用到汇编语言的结构化
25、数据结构。,与前述的字节、字类型数据不同,一个结构必须先经定义后才可以说明属于这种结构类型的变量,这是因为结构的组成是千变万化的。所以围绕结构定义,有两种伪指令语句:,2. 结构变量说明与赋初值语句,1. 结构类型说明语句(STRUC/ENDS),3-42,3.2.5 结构定义伪指令,语句格式: 结构名 STRUC ;结构体,由数据定义语句构成 结构名 ENDS,DATE STRUC MONTH DB ? DAY DB ? YEAR DW ? DATE ENDS,结构的定义明确地描述了该结构的组织形式,它告诉汇编程序属于这种组织形式的变量使用内存的模式。例如:,1. 结构类型说明语句(STRU
26、C/ENDS),3-43,语句格式: 变量名 结构名 域值表,例如: VAR DATE ,3. 结构的引用 有两种方法: 结构变量名.域名 基址或变址寄存器.域名,MOV AX, VAR.YEAR MOV CL, VAR.DAY 上述引用也可用如下方法: MOV BX,OFFSET VAR MOV AX,BX.YEAR MOV CL,BX.DAY,3.2.5 结构定义伪指令,2. 结构变量说明与赋初值语句,3-44,3.3 汇编语言编程环境,与其它程序设计语言一样,汇编语言程序的开发过程可归结为:,就需求分析、模块划分和算法确定等工作而言,各种程序设计语言是类似的,均可按软件工程的方法进行,但
27、编程和调试则因程序设计语言而异。,需求分析 根据需求和规模等因素划分模块 确定各功能模块的求解算法、并定义所需的数据结构 进行编程和调试,3-45,对汇编语言而言,根据数据结构和算法进行编码到形成可用程序的过程如下:,3.3 汇编语言编程环境,3-46,一、汇编程序的操作步骤: 1、建立源程序文件(EDIT),扩展名为.ASM 2、汇编(MASM或ASM)源程序,生成目标文件“.OBJ”(.LST .CRF) 3、程序连接(LINK),生成“.EXE”文件 4、执行程序 C:MASM50文件名 5、调试程序 C:MASM50 DEBUG 文件名.EXE,3-47,二、执行宏汇编程序 1、汇编过
28、程 MASM 文件名; ;生成OBJ文件 MASM 文件名,;生成OBJ、LST MASM 文件名,; ;生成OBJ、LST、CRF三个文件 2、列表文件(.LST) 可用TYPE显示,包括三个部分 源程序和目标程序清单 段信息汇总表:各段所占存储空间的长度,各段的定位类型,段的组合类型 符号汇总表,3-48,3、交叉索引文件(.CRF) 列出了源程序中定义的符号(标号、变量)和程序中引用这些符号的情况。 三、执行连接文件 连接程序是把 一个或多个独立的目标程序模块装配成一个可重定位的可执行文件(.EXE)。 1、连接程序执行过程 LINK 文件名; (文件名.OBJ) 2、内存映射文件 (
29、.MAP),3-49,LINK 文件名,; 除了产生执行文件外,还连接产生内存映射文件(.MAP),它给出每个段的地址分配情况及长度。,3-50,DOS操作系统和ROM BIOS系统各为用户提供了一组例行子程序,用于完成基本I/O设备、内存、文件和作业的管理,以及时钟、日历的读出和设置等功能。,3.4 DOS/BIOS功能调用,3-51,INT 21H的调用方法 传送入口参数到指定寄存器中 功能号送入AH寄存器中 INT 21H 1、键盘键入字符并加回显(1号调用) MOV AH,1 INT 21H ;(AL)键盘键入字符,3-52, BUF DB 20 DB ? DB 20 DUP(?) M
30、OV DX,OFFSET BUF MOV AH,0AH INT 21H,3-53,3、输出单字符(2号调用) 入口参数:(DL)=显示字符 MOV DL,A MOV AH,2 INT 21H,3-54,4、输出字符串(9号调用) 入口参数:DS:DX=字符串首地址 功能:在屏幕上显示字符串(不含$) BUF DB GOOD BY $ MOV DX,OFFSET BUF MOV AH,9 INT 21H 5、返回操作系统(4CH调用) MOV AH,4CH INT 21H,3-55,顺序结构 分支结构 循环结构,3.5 三种基本结构程序的设计,程序的基本结构形式有三种:,理论上,三种基本结构是完
31、备的,即任何功能的程序都可由顺序、分支和循环三种结构实现。,3-56,3.5.1 顺序结构程序设计,顺序程序又称直线程序。其特点是顺序执行的,无分支,无循环,也无转移,只作直线运行。,在实际应用中,纯粹用顺序结构编写的完整程序很少见,但是在程序段中它却是大量的存在。所以掌握它是编写复杂应用程序的基础。,3-57,3.5.2 分支结构程序设计,在许多实际问题中,往往需要根据不同的情况和给定的条件做出不同的处理。要设计这样的程序,必须事先把各种可能出现的情况及处理方法都编写在程序中,以后计算机运行程序时,可自动根据运行的结果做出判断,有条件地选择执行不同的程序段,按这种要求编写的程序称为分支程序。
32、,3-58,IF 条件 THEN 分支程序,IF 条件 THEN 分支1 ELSE 分支2,分支程序的结构有三种形式:,3.5.2 分支结构程序设计,3-59,1. 利用比较与条件转移指令实现分支,这种方法适合于不完全分支和完全分支这两种结构,对分支较少的多分支结构也可用。,3.5.2 分支结构程序设计,3-60,例3.9程序:,DATA SEGMENT X DB 0F8H Y DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AL,X ;取变量X的值 CMP AL,0 ;X与
33、0比较 JG BIGR JE FINISH ;X=0,Y=0 MOV AL,0FFH ;X 0,Y=1 FINISH: MOV Y,AL ;保存函数值Y MOV AH,4CH INT 21H CODE ENDS END START,3.5.2 分支结构程序设计,3-61,这种方法适应于多分支结构。有三种跳转表:,3.5.2 分支结构程序设计,2. 利用跳转表实现分支,3-62,使用跳转表实现分支时,要特别注意表内地址分支和表内指令分支两种结构跳转表的定义方法和正确的寻址方式。,表内地址分支在数据段定义跳转表,用存储器间接寻址; 表内指令分支在代码段定义跳转表,用寄存器间接寻址。,3.5.2 分
34、支结构程序设计,3-63,设某控制程序可完成8种产品的加工,每种加工程序对应一个数字(18)。现要求根据输入的值去加工相应产品。假设8 种加工程序段与主程序在同一代码段中。,3.5.2 分支结构程序设计,例3.10,方法一:用表内地址分支实现 此时,跳转表在数据段定义,转移要用存储器间接寻址的跳转指令。,3-64,例3.10 表内地址分支程序,.486 DATA SEGMENT USE16 DATA DISP DB Error repeat input DB 0AH,0DH,$ BASE DD SBR1,SBR2,SBR3,SBR4 DD SBR5,SBR6,SBR7,SBR8 DATA EN
35、DS CODE SEGMENT USE16 CODE ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX INPUT: MOV AH,1 ;输入数字序号 INT 21H CMP AL,1 JB ERR CMP AL,8 JA ERR SUB AL,1,AND EAX,0000000FH JMP BASEEAX*4 SBR1: SBR2: SBR8: ERR: CMP AL,E JZ EXIT MOV DX,OFFSET DISP MOV AH,09H INT 21H JMP INPUT EXIT:MOV AH,4CH INT 21H CODE
36、 ENDS END START,3.5.2 分支结构程序设计,此题也可用表内指令分支实现。这时,跳转表要在代码段定义,转移则要用寄存器间接寻址的跳转指令。,3-65,.486 DATA SEGMENT USE16 DATA DISP DB Error repeat input DB 0AH,0DH,$ DATA ENDS CODE SEGMENT USE16 CODE ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX INPUT: MOV AH,1 ;输入数字序号 INT 21H CMP AL,1 JB ERR CMP AL,8 JA ER
37、R SUB AL,1 AND AX,000FH MOV BX,AX SHL BX,1 ADD AX,BX MOV BX,OFFSET BASE,ADD BX,AX JMP BX BASE: JMP SUB1 ;跳转表 JMP SUB2 JMP SUB8 SUB1: SUB2: SUB8: ERR: CMP AL,E JZ EXIT ;按E键结束 MOV DX,OFFSET DISP MOV AH,09H ;显示提示信息 INT 21H JMP INPUT ;转重输入字符 EXIT: MOV AH,4CH INT 21H CODE ENDS END START,3.5.2 分支结构程序设计,方法
38、二: 用表内指令分支,3-66,初始化部分 循环体 循环修改 循环控制,3.5.3 循环结构程序设计,凡要重复执行的程序段都可按循环结构设计。采用循环结构,可简化程序书写形式,缩短程序长度,减少占用的内存空间。,循环结构程序的组成,循环结构的程序一般包括下面几个部分:,3-67,循环结构的组织方式,有两种组织循环结构的方式:,3.5.3 循环结构程序设计,3-68,循环结束的控制方式,计数控制 条件控制 状态控制 逻辑尺控制,3.5.3 循环结构程序设计,常用的循环结束控制方式有以下四种:,3-69,1. 计数控制循环程序设计,循环次数已知时用计数控制循环,这时常用CX作循环计数器,用循环指令
39、LOOP控制循环。也可用其他通用寄存器作循环计数器,用DEC和JNZ指令控制循环。,3.5.3 循环结构程序设计,例3.11 编写程序,将ASCII码表示的5位十进制数(65535)转换成16位二进制数,并存储起来。,解:设X=Xn-1X1X0为十进制数,则X转换为二进制数的一般方法为: X=Xn-110n-1+X1 10+X0,3-70,例3.11 程序,3.5.3 循环结构程序设计,DSEG SEGMENT ASCDEC DB 23333 BINAY DW 0 MULTIPLE DW 1 DSEG ENDS CSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START
40、:MOV AX,DSEG MOV DS,AX MOV CX,10 ;SI指向ASCII码数首址 LEA SI,ASCDEC DEC SI ;BX指向ASCII码数个位 MOV BX,5,NEXT:MOV AL,BX+SI AND AX,0FH ;计算当前十进制位对应的二进制数 MUL MULTIPLE ADD BINAY,AX ;累加求和 MOV AX,MULTIPLE ;计算下一十进制位对应的权值 MUL CX MOV MULTIPLE,AX DEC BX JNZ NEXT ;未完继续 MOV AH,4CH INT 21H CSEG ENDS END START,3-71,当循环次数未知时,
41、就要用条件或状态信号来控制循环。用条件控制时,常用比较指令CMP与条件转移指令Jcc结合控制循环结束. 用状态控制时,状态信号既可由外设提供,也可由其他任务或过程提供,这时常用测试指令TEST与条件转移指令Jcc结合控制循环结束。,3.5.3 循环结构程序设计,2. 条件/状态控制循环程序设计,3-72,例3.12 将16位二进制数,转换成等值的十进制数从显示器输出。,3.5.3 循环结构程序设计,解:设X为任意无符号十进制数,则X可表示为:,用10除X,得:,即可用连续“除10取余”的方法,依次求得十进制数的个、十、百、千位、,直到an-1。,3-73,例3.12 程序,DATA SEGME
42、NT WORD INTEGER DW 12345 ;定义存放ASCII码十进制数变量区 ASCVAL DB 5 DUP( ) DB 0AH,0DH,$ DATA ENDS CODE SEGMENT WORD ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX LEA SI,ASCVAL+4 MOV AX,INTEGER MOV CX,10 ;CX为除数,AGAIN:CMP AX,10 ;商小于10? JB DONE ;小于10结束 XOR DX,DX ;扩展被除数 DIV CX ;(DX:AX)/(CX) ;转换成ASCII码数 OR DL,3
43、0H MOV SI,DL;保存十进制数位 DEC SI JMP AGAIN DONE: OR AL,30H MOV SI,AL MOV DX,OFFSET ASCVAL MOV AH,09H ;显示十进制数 INT 21H MOV AX,4C00H INT 21H CODE ENDS END START,3.5.3 循环结构程序设计,3-74,循环不规则时使用的一种循环控制方法,3.5.3 循环结构程序设计,3. 逻辑尺循环程序设计,例3.13 设有数组:,定义一个二进制位序列称为逻辑尺 1100010011 每个数组元素zi对应一位,该位为1,表示计算zi时对应数组元素相加,否则相减。,3-
44、75,例3.13 程序,START:MOV AX,DATA MOV DS,AX MOV BX,SOCBEH ;取逻辑尺 MOV CX,10 ;置循环次数 MOV SI,0 AGAIN:MOV AX,XSI ;取xi SHL BX,1 JNC L1 ADD AX,YSI ;求和 JMP L2 L1: SUB AX,YSI ;相减 L2:MOV ZSI,AX ;保存zi ADD SI,2 LOOP AGAIN EXIT: MOV AH,4CH INT 21H CODE ENDS END START,DATA SEGMENT X DW x1,x2,x3,x4,x5 DW x6,x7,x8,x9,x1
45、0 Y DW y1,y2,y3,y4,y5 DW y6,y7,y8,y9,y10 Z DW 10 DUP (?) SOCBEH DW 1100010011000000B DATA ENDS STACK SEGMENT STACK STN DB 100 DUP (?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,SS:STACK,DS:DATA,3.5.3 循环结构程序设计,3-76,3.6 子程序设计与调用,3.6.0 子程序设计概述 3.6.1 主程序与子程序的接口 3.6.2 主程序与子程序间的参数传递,3-77,3.6.0 子程序设计概述,同一个程序中,
46、往往有许多地方都需要执行同样的一项任务(一段程序),而该任务又并非规则情况,不能用循环程序来实现,这时可以对这项任务独立地进行编写,形成一个子程序或过程。,3-78,3.6.0 子程序设计概述,从子程序返回主程序则简称为“返主”,通常将主程序向子程序转移叫子程序调用或过程调用,简称“转子”,子程序结构如图所示:,3-79,正确使用CALL/RET指令 转子和返主过程中的现场保护和恢复, 主程序与子程序所使用的存储单元和寄存器尽量分开,互不干扰。,现场保护和恢复又有两种方法:,3.6.1 主程序与子程序的接口,主程序与子程序的接口主要解决两大问题:,3-80,SUBR PROC PUSH AX
47、PUSH BX ;子程序体 POP BX POP AX RET SUBR ENDP 子程序,这时,既可在子程序中保存和恢复,又可在主程序中保存和恢复。例如:, PUSH AX PUSH BX CALL SUBR POP BX POP AX 主程序,3.6.1 主程序与子程序的接口, 将“现场”通过堆栈保存和恢复,3-81,主程序在调用子程序时,往往要向子程序传递一些参数;同样,子程序运行后也经常要把一些结果传回给主程序。主程序与子程序之间的这种信息传递称为参数传递。,一般将子程序需要从主程序获取的参数称为入口参数,而将子程序返回给主程序的参数称为出口参数。 入口参数使子程序可以对不同数据进行相同功能的处理,出口参数使子程序可送出不同的结果至主程序。,3.6.2 主程序与子程序的参数传递,3-82,常用的参数传递方法有:,寄存器传递法 存储器传递法 堆栈传递法,具体采用何种方法要根据情况事先约定好,有时可能同时采用多种方法。,3.6.2 主程序与子程序的参数传递,调用前,主程序将参数保存在某些通用寄存器中,子程序则直接引用寄存器中的参数。出口参数也可通过寄存器返回给主程序。,调用前,主程序将参数存放到内存的某一区域或内存变量中,子程序到此约定的参数区或内存变量中获取参数,结果也可通过约定的存储变量返回给主程序。,主程序与子程序将要传递的信息放在堆
链接地址:https://www.31doc.com/p-3195691.html