4章汇编程序设计
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
;将C清零 ;送被加数首址 ;送加数首址 ;取被加数低字节 ;两个低字节相加 ;低字节和存人被加数低字节 ;修改指针,指向被加数高字节 ;修改指针,指向加数高字节 ;取被加数高字节 ;高字节相加 ;存结果
【例4-3】编写16位二进制数求补程序 二进制数的求补可归结为“求反加1”的过程,求反可用 CPL指令实现;加1时应注意,加1只能加在低8位的最低位上。 因为现在是16位数,有两个字节,因此要考虑进位问题,即低8 位取反加1,高8位取反后应加上低8位加1时可能产生的进位, 还要注意这里的加1不能用INC指令,因为INC指令不影响CY标 志。 ORG 0200H 程序如下: MOV A ,R0 ;低8位送A CPL A ;取反 ADD A ,#01H ;加l MOV R2 ,A ;存结果 MOV A ,R1 ;高8位送A CPL A ;取反 ADDC A ,#00H ;加进位 MOV R3 ,A ;存结果(R1R0---R3R2) END
X Y 试编写程序,根据X的值求出Y,并放回原单元。 解 取出X后先做取值范围的判断,用累加器A状态转 移指令判断X是否为0,用位状态转移指令判断X是大 于0还是小于0。程序流程图如图4.3所示。 程序如下:
MOV A,30H JZ ZER0 JNB ACC.7,PLUS ADD A,#5 MOV 30H,A PLUS: SJMP $ ZERO: MOV 30H,#20H SJMP $ END
4.2 顺序程序设计
顺序结构程序是一种最简单、最基本的程序(也称为简单 程序),它是一种无分支的直线形程序,按照程序编写的顺序 依次执行。 【例4-1】 两个8位无符号数相加,和仍为8位。 假设两个无符号数X1 , X2 分别存放于内部RAM60H、 61H单元中,求其和并将和送入62H单元。 程序如下: ORG 0000H CLR C MOV R0 ,# 60H ;设R0为数据指针 MOV A ,@R0 ;取X1 1NC R0 ADDC A ,@R0 ;X1+X2 1NC R0 MOV @R0,A ;保存结果 END
【例4-2】两个无符号双字节数相加。设被加数存放在内部存 储器30H(高位字节)、31H(低位字节)单元,加数存放在内 部存储器40H(高位字节)、41H(低位字节)单元,和存入30H (高位字节)、31H(低位字节)单元。 程序如下: ORG 0000H CLR C MOV R0 ,#31H MOV R1 ,#41H MOV A ,@R0 ADD A ,@R1 MOV @R0 ,A DEC R0 DEC R1 MOV A,@R0 ADDC A,@R1 MOV @R0 , A END
4.2.2 伪指令语句
伪指令并不是真正的指令,也不产生相应的机器 码,它们只是在计算机将汇编语言转换为机器码时, 指导汇编过程,告诉汇编程序如何汇编。下面介绍一 些MCS-51汇编程序常用的伪指令。 (1)汇编起始伪指令ORG 格式:[标号:] ORG 16位地址 功能:规定程序块或数据块存放的起始地址。如: ORG 8000H START: MOV A ,#30H …… 该指令规定第一条指令从地址8000H单元开始存放, 即标号START的值为8000H。
第四章 汇编语言程序设计
4.1 汇编语言程序设计概述
所谓程序设计,就是按照给定的任务要求,编写 出完整的计算机程序。要完成同样的任务,使用的方 法或程序并不是唯一的。因此,程序设计的质量将直 接影响到计算机系统的工作效率、运行可靠性。 前面我们学过了汇编语言形式的指令系统,本章 重点介绍汇编语言程序结构以及如何利用汇编语言指 令进行程序设计的方法。
CJNE AJMP LOOPl: JNC CJNE AJMP LOOP2: FH: JC RET A,55H,LOOP1 FH JW A,54H,LOOP2 FH SW ;Ta≠T55,转向LOOPl ;Ta=T55,返回 ;若(CY)=0,表明Ta>T55,转降温处理程序 ;Ta≠T54,转向LOOP2 ;Ta=54,返回 ;若(CY)=1,表明Ta<T54,转升温处理程序 ;T55≥Ta≥T54,返回主程序
Y
循环结束?
N Hale Waihona Puke Baidu 环处理 循 环修改
循环结束?
Y 结 束处理 结束 ( a)先执行后判断 结 束处理 结束 (b)先 判断 后执行
二、程序清单
ORG START : MOV LOOP: MOV MOV DEL1: DEL2: DEL3: MOV MOV DJNZ DJNZ DJNZ RL AJMP END OOOOH A,#01H P1,A R1,#10H R2,#200 R3,#126 R3,DEL3 R2,DEL2 R1,DEL1 A LOOP
;取数送A ;除数100送B中 ;商(百位数BCD码)在A中,余数在B中 ;百位数送22H ;余数送A做被除数 ;除数10送B中 ;十位数BCD码在A中,个位数在B中 ;十位数BCD码移至高4位 ;并入个位数的BCD码 ;十位、个位BCD码存人21H
查表
[例4-5]一变量放在内部RAM 的20H,取值为00H-05H。 编写程序,求该变量的平方值,将结果放片内21H ORG 1000H START:MOV DPTR, #2000H; or MOV DPTR, #TABLE MOV A, 20H MOVC A, @A+DPTR MOV 21H, A SJMP $ ORG 2000H TABLE: DB 00, 01, 04, 09, 16, 25 END
【例4-4】编程将20H单元中的8位无符号二进制数转换成3位 BCD码,并存放在22H(百位)和21H(10位,个位)两个单元中。 程序如下: ORG 1000H MOV A ,20H MOV B ,# 64H DIV AB MOV 22H ,A MOV A,B MOV B , #0AH DIV AB SWAP A ORL A,B MOV 21H , A END
开始 (30H) A
A=0?
A>0?
20H (30H)
(30H)
(30H)+5
结束 图4.3 [例4-5]程序框图
【例4-7】内部RAM40H和41H单元中各有 一无符号数,比较其大小,将大数存放于内部 RAM60H单元,小数存放于内部RAM61H单元, 如两数相等,则分别送往这2个单元。 解 用比较不等转移指令CJNE比较力两个 无符号书,先确定它们是否相等,若不相等时 再根据借位标志确定这两个无符号书的大小。 程序框图如图4.4所示。 程序如下:
ORG SUM: MOV MOV SUM: MOV MOV LP: ADD JNC INC LP1: INC DJNZ MOV END
2000H R0,#40H R5,#0AH A,#00H R2,A A,@R0 LP1 R2 R0 R5,LP R3,A ;若有进位,和的高八位+1 ;地址指针+1 ;判循环结束条件 ;存和的低八位 ;设地址指针 ;计数器初值送R5
A (41H)
Y
N
A与(61H)交换
A
$
(60H)
结束
图4.4 [例4-6]程序框图
【例4-8】某温度控制系统,采集的温度值(Ta)放在累加器 A中。此外,在内部RAM54H单元存放控制温度下限(T54), 在55H单元存放控制温度上限(T55)。若Ta >T55,程序转向JW (降温处理程序);若Ta<T54,则程序转向SW(升温处理程 序);T55≥Ta≥T54,则程序转向FH(返回主程序)。 程序如下:
4.1.1 汇编语言程序设计步骤
使用汇编语言设计一个程序大致上可分为以下几个步骤。 (1) 分析题意,明确要求。 (2) 确定算法。 (3) 画程序流程图,用图解来描述和说明解题步骤。
图4.1 常用的流程图符号
(4) 分配内存工作单元,确定程序与数据区的存放地址。 (5) 编写源程序 (6) 程序优化。 (7)上机调试、修改和最后确定源程序。
【例4-11】从内存BLOCK单元开始有一个无符号 数的数据块,其长度为LEN,试求出其最大值,并存 入MAX单元。 这是一个搜索问题。这里采用依次进行比较和取 代的方法来寻找最大值。具体做法是:先取出第一个 数作为基准,和第二个数比较,若比较结果基准数大, 不作变动;若比较结果基准数小,则用大数来代替原 基准数,然后再和下一个数作比较。到比较结束时, 基准数就是所求的最大值。 为了进行两数的比较,采用两数相减以后判断CY 的值来确定哪个数大,这比用CJNE指令更简单。比较 时将基准数放在累加器A中。若A中先放零,比较次数 等于LEN;若A中先放人第一个数,则比较次数等于 LEN-1。采用R2作为计数器,R1作为地址指针。程序 流程如图4.9所示。
MOV MOV
A, 40H 61H, 41H
开始 (40H) (40H) A (60H)
CJNE AJMP LOOP:JNC
XCH AGEQ: MOV SJMP END
A , LOOP AGEQ
AGEQ A, 61H 60H, A
41H ,
;A≥(41H)则无借位 ;A<(41H)有借位;A与(61H)交 换
4.3 分支程序设计
图4.2 分支程序结构
图4.2(a) 结构使用条件转移指令来实现分支, 当给出的条件成立时,执行程序段A,否则执行程序 段B。 图4.2 (b) 结构使用散转指令JMP来实现多分支转 移,它首先将分支程序按序号的值来实现分支转移。
【例4-6】设补码X放在内部RAM30H单元中,函数 Y与X有如下的关系式:
(4)定义字节指令DB 格式:[标号:] DB 8位二进制数表 DB命令是从指定的地址单元开始,定义若干个8 位内存单元的内容。例如, ORG 1000H TAB; DB 23H,73, “6”, “B” TABl: DB 110B 以上伪指令经汇编以后,将对从1000H开始的若干 内存单元赋值: (1000H)=23H (1001H)=49H (1002H)=36H (1003H)=42H (1004H)=06H 其中36H和42H分别是字符6和B的ASCII码,其余 的十进制数(73)和二进制数(110B)也都换算为十 六进制数了。
;左移一位,下一个发光二极管亮
;使L1灯亮,其它不亮 ;从P1口输出到发光二极管 ;延时1秒,根据机器周期算
;循环
【例4-10】多个单字节数求知。 已 知 有 10 个 单 字 节 数 , 依 次 存 放 在 内 部 RAM 40H单元开始的数据存储区中,求和并将 结果存人寄存器R2、R3中(高位存R2,低位存 R3)。 本题中,要重复进行加法运算,因此采用 循环结构程序。循环次数就是数据块字节数,这 是已知的。在置初值时,将数据块长度置人寄存 器R5;将数据块首地址送人寄存器R0,即以R0 作为数据块的地址指针,采用间接寻址方式:每 做一次加法之后,修改地址指针,以便取出下一 个数来相加,并且使计数器R5减l。到R5减为0 时,求和结束。程序流程图如图4.8所示。
【例4-9】N路分支程序,N≤8。要求程序根据其运行 中所产生的寄存器R3的值,来决定如何进行分支。
MOV A ,R3 MOV DPTR ,#BRTAB MOVC A ,@A+DPTR JMP @A+DPTR BRTAB AJMP BR0 AJMP BR1 AJMP BR2 AJMP BR3 BR0: SETB P1.0 SJMP BRK BR1: SETB P1.1 SJMP BRK BR2: SETB P1.2 SJMP BRK BR3: SETB P1.3 BRK: SJMP BRK
(2)汇编结束伪指令END 格式:[标号:] END [表达式] 功能:结束汇编。 例如: ORG 2000H START: MOV A ,# 00H …… END (END START) 表示标号START开始的程序段结束。 (3)等值指令EQU 格式:字符名称 EQU 项 例如,TEST EQU R0 MOV A,TEST
(5)定义字命令 DW 格式:[标号:] DW 16位二进制数表 例如, ORG 1000H TAB: DW 1234H , 0ABH , 10 汇编后: (1000H)=12H (1001H ) = 34H (1002H ) = 00H ( 1003H ) = ABH (1004H ) =00H (1005H) =0AH DB、DW伪指令都只对程序存储器起作用,不能 用来对数据存储器的内容进行赋值或进行其它初始化 的工作。
4.4 循环程序设计
循环程序一般由4部分组成。 (1)置循环初值。 (2)循环体。 (3)循环修改。 (4)循环控制。 图4.7(a)结构是“先执行后判断”,适用于循环次数已 知的情况。 图4.7(b)结构是“先判断后执行”,适用于循环次数 未知的情况。
开始 置循环初 值
开始 置 循环初值
循 环处理 循 环修改 N