1、1,第四章 汇编语言程序设计,高级语言如C+,汇编语言如MCS-51指令,汇编,目标文件,按照语法格式编写源程序*.ASM *.C,按照语法格式将源程序翻译成机器代码,计算机识别的二进制代码*.OBJ,编译,目标文件,2,本章结构,4.1 单片机程序设计语言概述 4.4 汇编语言编辑和汇编及其伪指令 4.2 汇编语言程序的基本结构形式 顺序程序结构 分支程序结构 循环程序结构 4.3 汇编语言程序设计举例,3,4.1.1、 程序设计语言及语言处理程序,程序设计语言分:机器语言、汇编语言和中高级语言 1.机器语言: 硬件识别,二进制,无需翻译、直接执行,面向机器; 速度快,效率高,难以辨认和记忆
2、,易错,难修改。,4.1 概述,地址 机器码 源程序 ORG 2000H 2000H 78 30 MAIN: MOV R0,#30H2002H E6 MOV A,R0,4,2.汇编语言: 由字母,数字符号组成,翻译成机器语言再由CPU执行; 面向机器,编译后执行速度接近机器语言,易读,不易错,但必须熟悉指令系统,移植性差; 程序精细、具体,结构紧凑,运行时间精确,高效; 运算量大,实时性要求高时常用汇编。,地址 机器码 源程序 ORG 2000H 2000H 78 30 MAIN: MOV R0,#30H2002H E6 MOV A,R0,5,3.中高级语言: 面向过程和面向对象。参照数学语言
3、又类似日常会话语言。高级语言中,一条高级语言指令,代替几上百条汇编指令。直观,易学,便于移植(由编译器负责),也需经过编译、解释成机器代码后执行。 C、BASIC、C,6,4.1.2、汇编语言特点及其格式 P77,2.语句格式 标号: 操作码 操作数, ;注释 (1).标号: 标号是由18个ASCII字符组成,但头一个字符必须是字母,其余字符可以是字母、数字或其它特定字符。 不能使用本汇编语言已经定义了的符号作为标号,如指令助记符、伪指令记忆符以及寄存器的符号名称等。 标号后边必须跟以 “ :”。 同一标号在一个程序中只能定义一次,不能重复定义,大小写一样。 一条语句可以有标号,也可以没有标号
4、。标号的有无取决于本程序中的其它语句是否需要访问这条语句。,7,错误的标号 正确的标号 1BT: BT1: BEGIN BEGIN: TB十5T: TA5T: ADD: ADD1: 3)操作数:是参加运算的数据或者数据的地址。 4)注 释:解释说明,增加可读性,汇编时不产生任何机器码,8,4.1.3 程序设计基本方法,在能完成规定的功能任务基础上还要求:执行速度快、占用内存少、条理清晰、阅读方便、便于移植、巧妙而实用。 步骤: 1分析问题 2确定算法 3设计程序流程图 4分配内存单元 5编写汇编语言源程序 6汇编并调试程序,9,4.1.4、MCS-51汇编语言的伪指令: P93作用:告诉汇编程
5、序如何完成汇编,不产生机器码。 (1)、ORG:起始伪指令Origin 指明程序和数据块起始地址。指令地址 机器码 源程序 ORG 2000H 2000H 78 30 MAIN:MOV R0,#30H2002H E6 MOV A,R0ORG 3000H3000H 23 DB 23H,100,A 3001H 643002H 41,10,(2)、END 汇编结束伪指令。 P94例:START: END (3)、EQU 赋值伪指令。格式: EQU 赋值项可以是常数、地址、标号或表达式; 其值可以是8位或16位二进制数; 赋值后的字符名称可以当作地址使用,也可以当作立即数使用。 字符名称必须是以字母开
6、题的字母数字串,必须先前未定义过。 X1 EQU 2000H X2 EQU 0FH MAIN: MOV DPTR,#X1 ADD A,#X2,11,(4)DB定义字节伪指令 格式:标号:DB 将项表中的字节数据存放到从标号开始的连续字节单元; 项表可以是一个字节、用逗号隔开的字节串或中的ASCII字符串; 例如:ORG 2300H SEG: DB 0C2HDB 30H,97H,100,AC 汇编结果: 2300H=? 2301H=? 2302H=?,12,(5)DW定义字伪指令(Define Word) 格式:标号:DW 用于定义16位的地址表。 汇编后,每个16位二进制数按照低地址存高位字节
7、,高地址存放低位字节的顺序存放。 例如:ORG 1000H TAB: DW 2030H,8CH,AB 汇编后:(1000H)20H,(1001H)30H,13,(6)DS定义存储区伪指令 格式:标号 DS 从指定地址开始,保留指定数目的字节单元作为存储区备用。 例如:ORG 1000HDS 20 汇编后从1000H地址开始保留20个连续的单元。 注意: 对于MCS51单片机,DB/DW/DS伪指令只能对程序存储区使用,而不能对数据存储器使用。,14,(7)BIT位定义伪指令 格式: BIT 把一个可以位寻址的位单元赋给所规定的字符名称。 例如:X1 BIT 30HX2 BIT P1.0 汇编后
8、,位地址30H赋给了X1,P1.0对应的位地址(90H)赋给了X2。,15,4.2 汇编程序的基本结构,顺序程序结构 分支程序结构 单分支程序结构 多分支程序结构 循环程序结构,16,17,4.2.1 顺序程序结构,汇编语言程序中最简单、最基本的程序结构。 程序执行时一条接一条地按顺序执行指令,无分支、循环以及调用子程序。ORG 0000HLJMP MAIN MAIN: MOV A , #30HADD A , #58HMOV 30H , ASJMP $,18,顺序程序结构分析:找出关键的执行实际功能操作的指令,然后将其前面与该指令相关的指令规类为该指令的前期配置指令。并需要对指令占用的资源和操
9、作的影响有全局的把握。 MOV R0,#52H DEC R1 MOV A,R0 MOV R1,#55H MOV A,R0 ADDC A,R1 MOV A,R0 ADDC A,R1 MOV R0,A ADD A,R1 MOV R0,A CLR A MOV R0,A DEC R0 ADDC A,#00H DEC R0 DEC R1 MOV 20H,A,19,4.2.2 分支程序结构,程序分支是通过转移指令实现的,也称为选择结构。可分为单分支和多分支两类。 单分支程序结构,通过条件转移指令实现,即根据条件对程序的执行进行判断、满足条件则进行程序转移,不满足条件就顺序执行程序。可用指令JZ、JNZ、C
10、JNE、DJNZ;JC、JNC、JB、JNB、JBC。 多分支程序是首先把分支程序按序号排列,然后按序号值进行转移。指令:JMP A+DPTR,20,1、单分支程序结构,程序分支是通过条件转移指令实现的,即根据条件对程序的执行进行判断,满足条件则进行程序转移,不满足条件程序就顺序执行。( 1 )无条件转移:LJMP,AJMP,SJMP( 2 )条件转移:JZ、JNZ、CJNE和DJNZ等。( 3 )按位转移:JC、JNC、JB、JNB和JBC等。使用这些指令,可以完成为0、为1、为正、为负以及相等、不相等等各种条件判断。,21,例4.2 假定外部RAM中有ST1、ST2、ST3共3个连续单元,
11、其中ST1和ST2单元中分别存放着两个8位无符号二进制数,要求找出其中的大数并存入ST3中。 START: CLR CMOV DPTR,#ST1MOVX A,DPTR ;取第一个数MOV R2,AINC DPTRMOVX A,DPTR ;取第二个数SUBB A,R2JNC BIG1 ;第二个数大转BIG1XCH A,R2 ;第一个数大,整字节交换继续 BIG0: INC DPTRMOVX DPTR,A ;存大数RET BIG1: MOVX A,DPTR ;将大数存入ASJMP BIG0,22,2.多分支程序结构,常使用CJNE、JMP A+DPTR指令 1.多重单分支:多条CJNE指令 2.J
12、MP A+DPTR 与数据表配合:范围有限,256字节。 3.JMP A+DPTR 与转移指令配合:A中值为序号与转移指令字节数的乘积。 4.利用RET指令,通过堆栈操作实现:将分支地址从入口地址表取出后,压入堆栈,利用RET指令赋予PC分支地址。,23,2.1 使用多条CJNE指令 假定分支序号值保存在累加器A中,则可使用CJNE A, #data, rel,24,例4.3某温度控制系统,采集的温度值(Ta)放在累加器A中。此外,在内部RAM54H单元存放控制温度下限制(T54),在55H单元存放控制温度上限制(T55)。若Ta T55,程序转向JW(降温处理程序);若TaT55,转降温程序
13、CJNE A,54H,LOOP2 ;Ta T54,转向LOOP2AJMP FH ; TaT54,返回 LOOP2:JC SW ;若C1,表明TaT54,转升温程序 FH : RET,25,2.2 通过查数据表(地址表)的方法 首先在程序中建立一个差值表,将各分支入口地址与该表首地址的差值按序排列其中; 差值表首地址送DPTR; 分支序号值送A中; 通过JMP A+DPTR指令进行分支。,26,例: MOV A,R3MOV DPTR,#BRTABMOVC A,A+DPTRJMP A+DPTR BRTAB:DB BR0-BRTABDB BR1-BRTABDB BR2-BRTABDB BR3-BRT
14、AB BR0: MOV A,R0SJMP BRE BR1: MOVX A,R0SJMP BRE,BR2: MOV A,R1ANL A,#0FHANL P2,#0F0HORL P2,AMOVX A,R0 BR3: MOV DPL,R0MOV DPH,R1MOVX A,DPTR BRE: SJMP $,27,2.3 使用查转移指令表的方法 表中放的是转移指令 设置一个序号指针 转移指令表首地址送给DPTR 通过JMP A+DPTR指令进行分支,28,MOV DPTR,#3000HMOV A,R3CLR CRLC AJMP A+DPTR 3000H 3001H 3002H AJMP DS 3003H
15、 3004H AJMP XS 3005H 3006H AJMP CR,例:假定键盘上有3个按键,功能说明如下表,用程序实现:键值序号存放在R3中,29,2.4通过堆栈操作实现MOV DPTR,#BRTAB ;分支入口地址表首址MOV A,R3RL A ;分支转移值乘以2MOV R1,A ;暂存A值INC AMOVC A,A+DPTR ;取低位地址PUSH ACC ;低位地址入栈MOV A,R1 ;恢复A值MOVC A,A+DPTR ;取高位地址PUSH ACC ;高位地址入栈RET ;分支入口地址装入PC BRTAB: DW BR0 ;分支程序入口地址表DW BR1 DW BR127,30,4
16、.2.3 循环程序,循环程序一般由4部分组成: (1)置循环初值。 (2)循环体。 (3)循环修改。 (4)循环控制。 循环结构: 图(a)结构是“先执行后判断”,适用于循环次数已知的情况。 图(b)结构是“先判断后执行”,适用于循环次数未知的情况。,31,4.2.3 循环程序,32,例:设有一字符串以回车符为结束标志,并存放在内部RAM从40H单元开始的连续存储单元中,编写测试字符串长度的程序。 MOV R2,#0FFH ;设置长度计数器初值MOV R0,#3FH ;设置字符串指针初值 LOOP:INC R2INC R0CJNE R0,#0DH,LOOPRET,33,例:把内部RAM中其首地
17、址为data的数据串传送到外部RAM中以buffer为首地址的区域,直到发现“$”字符的ASCII码为止。同时规定数据串的最大长度为32个字节。,MOV R0,#dataMOV DPTR,#bufferMOV R1,#20H LOOP:MOV A,R0CLR CSUBB A,#24HJZ LOOP1MOV A,R0MOVX DPTR,AINC DPTRINC R0DJNZ R1,LOOP LOOP1:RET,34,4.2.4 子程序设计,一、子程序的概念 子程序:执行过程相同的部分编成一个独立的程序段。 子程序调用:控制从主程序转向子程序的过程 子程序返回:子程序指向完毕后返回主程序的过程 返
18、回地址:返回到主程序调用指令的下一条指令的地址,即断点地址。 子程序的嵌套:子程序内部还可以再调用另一个子程序。,35,4.2.4 子程序设计,二、子程序的调用返回 调用: 通过指令ACALL addr11和LCALL addr16来实现:先将PC中的内容(断点地址)压入堆栈保护,然后再将调用地址送入PC,转向子程序入口地址; 安排压栈指令保护现场,保护不希望被子程序更改内容的寄存器,返回后再恢复现场。 返回: 通过指令RET实现:将堆栈中的断点地址弹出送入 PC。 安排相应的指令,处理子程序提供的出口数据。,36,三、主程序与子程序的参数传递 入口参数和出口参数的存放参数传递; 用累加器或工
19、作寄存器来传递参数 程序编制简单,容易阅读。 工作寄存器数量有限,不能传递太多的参数; 用指针寄存器来传递参数 若参数在片内RAM中,可用R0或R1作指针寄存器; 若参数在外部RAM或程序寄存器中,可用DPTR作指针寄存器。 用堆栈来传递参数 调用前,主程序用PUSH指令将有关参数压入堆栈中。 进入子程序,通过堆栈指针来间接访问堆栈中的参数。子程序结束前,也可以把结果压入堆栈保存起来; 子程序返回后,主程序再用POP指令得到结果参数。,4.2.4 子程序设计,37,四、子程序及调用举例 例:求两个无符号数据块的最大值。设这两个数据块的首地址分别为30H和50H,每个数据块的首字节存放着该数据块
20、的长度,求最大值存入7FH中。先编写出求无符号数据块最大值的子程序,然后在主程序中通过两次调用该子程序,分别求出两个数据块的最大值,再比较他们的大小。 规划: 入口:数据块的首地址送入R1; 出口:最大值在A中 占用资源:A,R1,R2,38,主程序:ORG 0000HLJMP STARTORG 0100H STRAT: MOV R1,#30H ;置入口参数ACALL BMAX ;调用子程序MOV 7FH,A ;暂存最大值MOV R1,#50H ;置入口参数ACALL BMAX ;CLR CSUBB A,7FH ;比较两个最大值JC NEXT ;A小则转ADD A,7FH ;A大恢复AMOV
21、7FH,A NEXT: SJMP $,子程序: ORG 2000H BMAX: MOV R2,R1;取数据块长度DEC R2 ;设置循环计数值INC R1 ;修改指针MOV A,R1 ;取第一个数INC R1 ;指向第二个数 LOOP: CLR C ;SUBB A,R1 ;减法比较JNC LP1 ;无借位A大MOV A,R1 ;否则大者送ASJMP LP2 LP1: ADD A,R1 ;A大恢复A LP2: INC R1 ;修改地址指针DJNZ R2,LOOP ;未完继续比较RET ;比较完,返回,39,4.3 程序设计举例,4.3.1 算术运算程序 1.加减法运算 1.1 不带符号的多个单字
22、节数加法 R0数据指针;R1和的高位;R2和的低位;R3字节个数N -MOV R0,#21HMOV R3,#NMOV R1,#00HMOV R2,#00H LOOP: MOVX A,R0ADD A,R2MOV R2,AJNC LOOP1INC R1 LOOP1:INC R0DJNZ R3,LOOP,40,1.2不带符号的两个多字节数减法字节数N; 被减数单元地址R0; 减数单元地址R1;差地址R0 -CLR CMOV R2,#N LOOP :MOV A,R0SUBB A,R1MOV R0,AINC R0INC R1DJNZ R2,LOOPJC QAZ ;最高字节有借位转溢出处理RET,41,4
23、.3.1 算术运算程序,1.3 带符号数加减运算 减法运算:将减数的符号位取反,即可把减法运算按加法运算的原则来处理; 加法运算:首先要进行两数符号的判断。 符号相同,进行两数相加,并以被加数符号为结果符号; 符号不同,进行两数相减。 若差数为正,则为最后结果,并以被减数符号为结果符号; 若差数为负,则应将其差数取补,并把被减数的符号取反作为结果符号。,42,2. 乘法运算 例4.9:双字节无符号数乘法程序:R2R3R6R7=R2R3R4R5,MULTD:MOV A,R3 ;计算R3R7MOV B,R7MUL ABMOV R4,B ;暂存部分积R3R7HMOV R5,A ;低字节存入R5MOV
24、 A,R2 ;计算R2R7MOV B,R7MUL ABADD A,R4 ;累加R3R7H+R2R7LMOV R4,A ;暂存部分积CLR AADDC A,B ;R2R7H+CYAMOV R7,A ;暂存AMOV A,R3 ;计算R3R6MOV B,R6MUL ABADD A,R4 ;R3R7H+R2R7L+R3R6LMOV R4,AMOV A,R7ADDC A,B ;R2R7H+R3R6H低位进位,MOV R3,A ;暂存部分积 CLR A RLC A ;进位移入A最低位 XCH A,R2 ;计算R2R6 MOV B,R6 MUL AB ADD A,R3 ;R2R7H+R3R6H+R2R6L
25、MOV R3,A MOV A,R2 ;进位送入A ADDC A,B ;R2R6H+进位 MOV R2,A :R2R6H进位送R2 RET,R2 R3 R6 R7,R3R7H R3R7L,R2R7H R2R7L,R3R6H R3R6L,R2R6H R2R6L,43,4.3.2 数制转换程序,1.十六进制转换为ASCII码 例:2位16进制数存放于50H单元; 转换结果存放于51H和52H单元; MAIN:主程序;HASC:子程序,HASC: DEC SPDEC SPPOP ACCANL A,#0FHADD A,#7MOVC A,A+PCPUSH ACCINC SPINC SPRET ASCTAB
26、:DB “01234567”DB “89ABCDEF”,MOV SP,#3FH MAIN: PUSH 50HACALL HASCPOP 51HMOV A,50HSWAP APUSH ACCACALL HASCPOP 52H,44,2.ASCII码转换为16进制数 “字符0”“字符9”的ASCII码值为“30H”“39H”,它们与30H之差恰好为“00H”“09H”,结果均0AH。 “字符A”“字符F”的ASCII码值为“41H”“46H”,它们各自减去37H后恰好为“0AH”“0FH”,结果0AH。 例:把外部RAM30H3FH单元中的ASCII码依次转换为16进制数,并存入内部RAM60H6
27、7H单元之中。,45,R0:ASCII码地址指针;R1:16进制数存放地址指针;R7:16进制数字节个数 MAIN: MOV R0,#30HMOV R1,#60HMOV R7,#08H AB: ACALL TRAN ;调用转换子程序SWAP A ;A高低4位交换MOVX R1,A ;存放于外部RAMINC R0ACALL TRAN ;调用转换子程序XCHD A,R1 ;16进制数拼装INC R0INC R1DJNZ R7,AB ;继续 HALT: AJMP HALT TRAN: CLR C ;清进位位MOVX A,R0 ;取ASCII码SUBB A,#30H ;减30HCJNE A,#0AH,
28、BBAJMP BC BB: JC DONE BC: SUBB A,#07H ;大于等于0AH,再减07H DONE: RET,46,3.单字节二进制数(0FFH)转换为双字节BCD码(0255) 入口:A二进制数 出口:存入R0所指定的单元 占用资源:A、B、R0 - BINBCD: MOV B,#100 DIV AB ;A=百位数MOV R0,A INC R0 MOV A,#10 XCH A,B DIV A,B ;A=十位数;B=个位数SWAP A ;十位移到高半字节ADD A,B ;形成十位和个位压缩的BCD码MOV R0,A RET,47,4.3.3 定时程序,1.单循环定时程序 NOP
29、:1个机器周期 DJNZ:2个机器周期MOV R5,#TIME LOOP: NOPNOPDJNZ R5,LOOP 该循环定时时间:4机器周期TIME 最大定时时间:4机器周期?,48,2.较长时间的定时程序 采用多重循环的方法 例:双重循环MOV R5,#TIME1 ;1个机器周期 LOOP2: MOV R4,#TIME2 ;1个机器周期 LOOP1: NOP ;1个机器周期NOP ;1个机器周期DJNZ R4,LOOP1 ;2个机器周期DJNZ R5,LOOP2 ;2个机器周期RET ;2个机器周期 定时时间: (TIME24+2+1)TIME1机器周期(2+1)机器周期,49,例4-12:
30、 延时程序设计。设8051单片机使用的晶振为12MHz,要求用软件方法实现60ms延时程序。分析:2us3000060msDELAY: MOV R7,#200 ;1DL1: MOV R6,#150 ;1DL2: DJNZ R6,DL2 ;2 DJNZ R7,DL1 ;2SJMP $ 准确延时时间:(300us2us+1us)200+1us60.601ms,50,3.调整定时时间 通过在循环程序段中增减指令的方法进行微调; 这些指令起到调节机器周期的作用,称为哑指令,例如NOP。 使用哑指令注意: 不破坏有用存储单元的内容; 不破坏有用寄存器的内容; 不破坏有用标志位的状态;,51,例:晶振频率
31、6MHzMOV R0,#TIME ;1 LOOP: ADD A,R1 ;1INC DPTR ;2NOP ;1DJNZ R0,LOOP ;2,52,4.以一个基本的延时程序满足不同的延时要求 先设计一个基本的延时程序,使其延时时间为各定时时间的最大公约数; 然后以此基本程序为子程序,通过不同的循环次数进行调用。 例如:要求定时时间为5us,10us,20us;设计一个1us的延时子程序,分别循环5次、10次、20次。,53,4.3.4 查表程序,1.查表指令 MOVC A,A+DPTR 可给DPTR赋予16位的地址; 查表范围64KB; 数据表格可以在64KB范围内任意设置,可被多个程序块公用。
32、 MOV A,A+PC PC不能赋值,其基址固定; 查表范围256B; 表格只能被本程序段使用。,54,例1 近程查表 设程序中的数据表格为: 1010H:02H 1011H:04H 1012H:06H 1013H:08H执行程序: 1000H:MOV A,#0DH 1002H:MOVC A,A+PC 1003H:MOV R0,A 结果为:(A)= 02H ,(R0)= 02H ,(PC)= 1004H,55,例2 远程查表 设程序中的数据表格为:执行程序: 1000H:MOV A,#10H 1002H:PUSH DPH 1004H:PUSH DPL 1006H:MOV DPTR,#7000H
33、 1009H:MOVC A,A+DPTR ; 100AH: POP DPH 100CH:POP DPL 结果为:(A)= ,(PC)= ,(DPTR)=,7010H:02H 7011H:04H 7012H:06H 7013H:08H,02H 100EH 原值高低字节互换,56,4.3.5数据极值查找程序,例:内部RAM20H单元开始存放8个无符号8位二进制数,找出其中的最大数。 假定在比较过程中,以A存放最大数,与之逐个比较的另一个数放在2AH单元中。比较结束后,把查到的最大数送到2BH单元。 占用资源 R0:数据区首址 R7:数据区长度,57,58,MOV R0,#20HMOV R7,#08
34、HMOV A,R0DEC R7 LOOP: INC R0MOV 2AH,R0CJNE A,2AH,CHK CHK: JNC LOOP1 ;A大,转移MOV A,R0 LOOP1: DJNZ R7,LOOPMOV 2BH,A HERE: AJMP HERE,59,4.3.6 数据排序程序,1.算法说明(冒泡法) 冒泡法:相邻数互换,类似气泡上浮。 每次冒上去的不一定是本次最小的数,但每次沉底的必是本次最大的数。,60,注: 每次冒泡都从前向后排定了一个大数(升序),因此每次冒泡所需进行的比较次数都递减1.实际编程时,为了简化程序,一般把各次的比较次数都固定为(n1)次。 对于n个数,理论上需进行
35、n1次冒泡才能完成排序。 判定排序是否完成的最简单方法是看各次冒泡中是否有互换发生。因此,一般控制程序结束不用计数法,而是使用设置互换标志的方法。,61,62,例:8个数连续存放在20H单元开始的内部RAM中,用冒泡法排序。 R7:比较次数计数器;F0:交换标志,“1”有交换,”0”无交换; R0:数据存储区首址;2AH:存后数;2BH:存前数; SORT: MOV R0,#20HMOV R7,#07HCLR F0 LOOP: MOV A,R0MOV 2BH,AINC R0MOV 2AH,R0CLR CSUBB A,R0JC NEXT ;前数小,不交换MOV R0,2BH ;前数大,交换DEC
36、 R0MOV R0,2AHINC R0SETB F0 NEXT: DJNZ R7,LOOPJB F0,SORTSJMP $,63,4.3.7 数据检索,1.顺序检索 把关键字与数据区中的数据从前向后逐个比较,判断是否相等。 例4:假定数据首址是内部RAM20H,数据区长度为8,关键字放在2BH单元,把检索结果的数据序号放在2CH单元。,64,资源:R0:数据区首址;R7:数据个数;R2:数据序号;2BH:关键字 -MOV R0,#20HMOV R7,#08HMOV 2CH,#00HMOV R2,#00HMOV 2BH,#KEY NEXT: INC R2CLR CMOV A,2BH ;取关键字S
37、UBB A,R0 ;与关键字比较JZ ENDPINC R0DJNZ R7,NEXTMOV R2,#00H ENDP: MOV 2CH,R2 ;送检索是否成功标志 HERE: AJMP HERE,65,2.对分检索 前提:数据已排好序; 取数组中间位置的数与关键字进行比较: 相等:则检索成功; 取数大于关键字,则下次对分检索的范围是从数据区起点到本次取数; 取数小于关键字,则下次对分检索的范围是从本次取数到数据区终点;,66,67,例:内部RAM中,首地址为data,其数据为按升序排好的无符号数。 2AH:存放检索范围的起点;2BH:存放检索关键字; R0:数据区首址,检索开始后为对分读数地址;
38、 R2:检索成功标志放入数据序号,不成功则置为0FFH; R3:检索次数计数器;R4:存放检索到的数据;R7:检索范围终点。 -MOV 2AH,#00HMOV R7,#DVLMOV 2BH,#KEYMOV R3,#01H LOOP1:MOV R0,#DATA ;数据区首址MOV A,2AHADD A,R7CLR CRRC A ;除2取整MOV R2,A ;存放取数序号CLR CSUBB A,2AH ;判断是否到范围边缘JZ LOOP3 ;相等则到达边缘,转移JNC LOOP2 ;取数大则转,68,MOV 2AH,R2 ;取数小,修改起点INC R3 ;检索次数加1SJMP LOOP1 ;继续
39、LOOP2:MOV A,R2 ;取数大,修改终点MOV R7,AINC R3SJMP LOOP1 ;继续 LOOP3:MOV R0,#DATA ;达到边缘,比较是否为关键字MOV A,R0CJNE A,2BH,LOOP4MOV R4,A ;是关键字SJMP LOOP5 LOOP4:MOV A,#0FFH ;非关键字,送OFF标志MOV R2,A LOOP5:SJMP LOOP5,69,练习,1.将两个多字节无符号数相加,设这俩个数分别放在外部RAM以1000H和1200H为首址的存储区中,数据长度放在R1中,相加结果存放到以1000H为首址的存储区中。,70,MOV DPL,#00HCLR C MADD: MOV DPH,#12HMOVX A,DPTRMOV R4, AMOV DPH,#10HMOVX A,DPTRADDC A,R4MOVX DPTR,A INC DPLDJNZ R1,MADDEND,