好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

汇编语言程序设计简介修改.ppt

79页
  • 卖家[上传人]:新**
  • 文档编号:605199528
  • 上传时间:2025-05-20
  • 文档格式:PPT
  • 文档大小:271KB
  • / 79 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 单击此处编辑母版标题样式,,单击此处编辑母版文本样式,,第二级,,第三级,,第四级,,第五级,,,*,第 4 章 汇编语言程序设计简介,第4章 汇编语言程序设计简介,4.1 伪指令,,,4.2 汇编语言程序设计,,汇编程序功能,,源程序,,(汇编指令程序),,汇编,目标程序,,(机器码指令程序),,汇编指令与机器码指令有一一对应的关系汇编程序是一种翻译程序,将源程序翻译成目标程序汇编程序的汇编过程,,,汇编有两种方法:手工汇编、机器汇编1、手工汇编:,,第一次汇编:确定地址,翻译成各条机器码,字符标号原样写出;,,第二次汇编:标号代真,将字符标号用所计算出的具体地址值或偏移,,量代换源程序,,目标程序,,地址,,ORG 1000H,,START:MOV R0,,2FH,,MOV R2,#00H,,MOV A,@R0,,MOV R3,A,,INC R3,,SJMP,NEXT,,LOOP:INC R0,,CJNE @R0,#44H,,NEXT,,,INC R2,,NEXT:DJNZ R3,,LOOP,,,MOV,2AH,,R2,,SJMP $,,END,,第一次汇编,第二次汇编,1000 A8,2F,,1002 7A00,,1004 E6,,1005 FB,,1006 0B,,1007 80,NEXT,,1009 08,,100A B644,NEXT,,100D 0A,,100E DB,LOOP,,1010 8A,2A,,1012 80FE,A82F,,7A00,,E6,,FB,,0B,,80,05,,08,,B644,01,,0A,,DB,F9,,8A,2A,,80FE,,2、机器汇编,,两次扫描过程。

      第一次扫描:,检查语法错误,确定符号名字;,,建立使用的全部符号名字表;,,每一符号名字后跟一对应值(地址或数)第二次扫描:,是在第一次扫描基础上,将符号地址转换成,,地址(代真);,,利用操作码表将助记符转换成相应的目标码4.1 伪 指 令,一、 汇编起始指令 ORG,,指令格式为: ,,ORG nn,,该指令的作用是指明后面的程序或数据块的起始地址, 它总是出现在每段源程序或数据块的开始 式中, nn为 16 位地址, 汇编时nn确定了此语句后面第一条指令或第一个数据的地址,此后的源程序或数据块就依次连续存放在以后的地址内, 直到遇到另一个ORG指令为止例: ORG 2000H,,MOV SP, #60H,,MOV R0, #2FH,,MOV R2, # 0FFH,,ORG伪指令说明其后面程序的目标代码在存储器中存放的起始地址是2000H, 即,,存储器地址 目标程序,,2000H 75 81 60,,2003H 78 2F,,2005H 7A FF,,二、等值指令EQU,,指令格式: ,,字符名称 EQU 数字或汇编符号,,功能: 使指令中的字符名称等价于给定的数字或汇编符号。

       使用等值指令可给程序的编制、调试、修改带来方便, 如果在程序中要多次使用到某一地址,由EQU指令将其赋值给一个字符名称, 一旦需要对其进行变动, 只要改变EQU命令后面的数字即可, 而不需要对程序中涉及到该地址的所有指令逐句进行修改 但要注意, 由 EQU等值的字符名称必须先赋值后使用, 且在同一个源程序中, 同一个标号只能赋值一次 例: ,,PA8155 EQU 8001H,,即给标号PA8155赋值为8001H三、 定义字节指令DB,,指令格式: ,,[标号: ] DB 8位二进制数表,,功能: 把 8 位二进制数表依次存入从标号开始的连续的存储单元中 ,,格式中, 标号区段可有可无, DB指令之后的 8 位二进制数表是字节常数或用逗号隔开的字节串, 也可以是用引号括起来的ASCII码字符串 (一个 ASCII字符相当于一个字节) 例: ,,ORG 1000H,,BUF1: DB 38H, 7FH, 80H,,BUF2: DB 45H, 66H,,ORG伪指令指定了标号BUF1的地址为1000H, 而DB伪指令是将其后的二进制数表38H, 7FH, 80H依次存放在1000H, 1001H, 1002H 3 个连续单元之中, BUF2也是一个标号, 其地址与前一条伪指令连续, 即1003H, 1004H地址单元中依次存放 45H, 66H。

      四、 定义字指令DW,,指令格式: ,,[标号:] DW 16 位数据表,,该指令的功能与DB相似, 区别仅在于从指定地址开始存放的是指令中的 16 位数据, 而不是字节串每个 16 位数据要占两个存储单元, 高8 位先存, 低 8 位后存, 这和MCS -51指令中的16位数据存放顺序是一致的五、 汇编结束指令END,,指令格式: ,,[标号:] END 地址或标号,,格式中标号以及END后面的地址或标号可有可无 ,,功能: 提供汇编结束标志汇编程序遇到 END后就停止汇编, 对 END以后的语句不予处理, 故 END应放在程序的结束处4.2 汇编语言程序设计,程序编写做到:,占用存储空间少;,运行时间短;,,程序的编制、调试及排错所需时间短;结构清晰,易读、易于移植按结构化程序设计思想,任何复杂程序都可由,,顺序结构、,,分支结构、,,循环结构,,等构成语句 3,语句 2,顺序结构,,入口,语句 1,出口,分支结构,入口,条件满足否?,,分支 1,出口,Y,N,,分支 2,循环结构,入口,,处理,,,修改条件,条件满足否?,Y,出口,N,,4.2 汇编语言程序设计,4.2.1 简单程序设计,例 1,两个无符号双字节数相加。

      设被加数存放于内部RAM的40H(高位字节), 41H(低位字节), 加数存放于50H(高位字节), 51H(低位字节), 和数存入 40H和41H单元中程序如下: ,,START: CLR C ; 将Cy清零,,MOV R0, #41H ; 将被加数地址送数据指针R0,,MOV R1, #51H ; 将加数地址送数据指针R1,,AD1: MOV A, @R0 ; 被加数低字节的内容送入A,,ADD A,@R1 ; 两个低字节相加,,MOV @R0, A ; 低字节的和存入被加数低字节中,,DEC R0 ; 指向被加数高位字节,,DEC R1 ; 指向加数高位字节,,MOV A, @R0 ; 被加数高位字节送入A,,ADDC A, @R1 ; 两个高位字节带Cy相加,,MOV @R0, A ; 高位字节的和送被加数高位字节,,RET,,例 2,将两个半字节数合并成一个一字节数。

      ,,设内部RAM 40H#, 41H单元中分别存放着 8 位二进制数, 要求取出两个单元中的低半字节, 并成一个字节后, 存入 50H单元中 程序如下:,START: MOV R1, #40H ; 设置R1为数据指针,,MOV A, @R1 ; 取出第一个单元中的内容,,ANL A, #0FH ; 取第一个数的低半字节,,SWAP A ; 移至高半字节,,INC R1 ; 修改数据指针,,XCH A, @R1 ; 取第二个单元中的内容,,ANL A, # 0FH ; 取第二个数的低半字节,,ORL A, @R1 ; 拼字,,MOV 50H, A ; 存放结果,,RET,,4.2.2 分支程序设计,图 4.1 分支结构框图,,(a) 单分支流程; (b) 多分支流程,,分支结构与分支程序设计,,结构:根据不同的条件,进行相应的处理通常用条件转移指令形成简单分支结构如: 判(A) = Z 或 NZ ,转移,,判(CY)= 1 或 0 ,转移,,判(bit)=1 或 0 ,转移,,CJNE 比较不相等转移,,,例 3,x#, y均为8位二进制数, 设 x存入R0, y存入R1, 求解:,程序如下: ,,START: CJNE R0, #00H, SUL1; R0中的数与00比较不等转移 MOV R1, #00H; 相等, R1← 0,,SJMP SUL2 ,,SUL1: JC NEG ; 两数不等, 若(R0)<0, 转向NEG,,MOV R1, #01H ; (R0)>0, 则 R1←01H,,SJMP SUL2,,NEG: MOV R1, #0FFH ; (R0)<0, 则 R1←0FFH,,SUL2: RET,,图 4.2,,,,例 4,比较两个无符号数的大小。

      ,,设外部 RAM 的存储单元 ST1和 ST2中存放两个不带符号的二进制数, 找出其中的大数存入外部 RAM 中的 ST3单元中图 4.3,,,程序如下:,,ORG 1000H ,,ST1 EQU 2000H,,ST2 EQU 2100H,,ST3 EQU 2200H,,START: CLR C ; 清零Cy,,MOV DPTR, #ST1 ; 第一个数的指针,,MOVX A, @DPTR ; 取第一个数,,MOV R2, A ; 保存,,MOV DPTR, #ST2 ; 第二个数的指针,,MOVX A, @DPTR ; 取第二个数,,CLR C,,SUBB A, R2; 两数比较,,JNC BIG1 ; 若第二个数大, 则转,,XCH A, R2; 第一个数大,,BIG0: MOV DPTR, #ST3 ,,MOVX @DPTR, A ; 存大数,,RET,,BIG1: MOVX A, @DPTR; 第二个数大,,SJMP BIG0,,RET,,4.2.3 循环程序设计,一、 循环程序,图 4.4,,,循环程序一般由四个主要部分组成: ,,(1) 初始化部分: 为循环程序做准备, 如规定循环次数、 给各变量和地址指针预置初值。

      ,,(2) 处理部分: 为反复执行的程序段, 是循环程序的实体, 也是循环程序的主体 ,,(3) 循环控制部分: 这部分的作用是修改循环变量和控制变量, 并判断循环是否结束, 直到符合结束条件时, 跳出循环为止4) 结束部分: 这部分主要是对循环程序的结果进行分析、 处理和存放循环结构不但使程序简练,而且大大节省存储空间循环程序包含四部分:,,1、,初始化部分 (循环计数器、变量置初值),,2、,循环处理部分(主体,需要重复执行的部分),,3、,循环控制部分(修改地址指针、修改变量、检测,,循环结束条件),,4、,循环结束部分(对结果分析、处理,存放结果),,先,处理,,后判断:,,开始,,初始化部分,,处理部分,,修改变量,,循环结束?,,结束部分,,结束,,Y,N,先判断,后处理:,,开始,,初始化部分,,修改变量,,循环结束?,,Y,结束部分,,结束,,N,处理部分,,,循环有:单循环、多重循环循环次数已知,可用计数器控制循环次数;,,循环次数未知,按问题条件控制循环是否结束1、单循环程序,,(1)循环次数是已知的程序,,,例 5,工作单元清零 ,,在应用系统程序设计时, 有时经常需要将存储器中各部分地址单元作为工作单元, 存放程序执行的中间值或执行结果, 工作单元清零工作常常放在程序的初始化部分中。

      ,,设有50个工作单元, 其首址为外部存储器8000H单元, 则其工作单元清零程序如下:,,CLEAR: CLR A ,,MOV DPTR, #8000H ; 工作单元首址送指针 MOV R2, 50 ; 置循环次数,,CLEAR1: MOVX @DPTR, A,,INC DPTR ; 修改指针,,DJNZ R2, CLEAR1; 控制循环,,RET,,例 6,设在内部 RAM的BLOCK单元开始处有长度为 LEN个的无符号数据块, 试编一个求和程序, 并将和存入内部 RAM的 SUM单元(设和不超过 8 位)BLOCK EQU 20H ,,LENEQU 30H,,SUM EQU 40H,,START: CLR A ; 清累加器A,,MOV R2, #LEN; 数据块长度送R2,,MOV R1, #BLOCK ; 数据块首址送R1,,LOOP: ADD A, @R1 ; 循环加法,,INC R1; 修改地址指针,,DJNZ R2, LOOP ; 修改计数器并判断,,MOV SUM, A; 存和,,RET,,,二、 多重循环,,,循环体中还包含着一个或多个循环结构,即双重或多重循环。

      例3、设8031使用12MHz晶振,试设计延迟100ms的延时程序内循环,外循环,解:延时程序的延迟时间就是该程序的执行时间,通常采用MOV,,和DJNZ二指令T = 12 / fosc = 12 / (12×10,6,)= 1us,,ORG 1000H,,DELAY:MOV R2,#CTS ;T = 1us,,LOOPS:MOV B,#CTR ;T = 1us,,LOOPR:DJNZ B,LOOPR ;2T = 2us,,DJNZ R2,LOOPS ;2T = 2us,,END,,,,内循环延时:,,(1 + 2 × CTR)T = 500us(假设),,则CTR = 250,,实际延时:[1 + 2 × 250] × 1us = 501us,,,,外循环延时:T +(501 + 2T)× CTS = 100ms = 100 000us,,所以 , CTS = 198.8 取 199,,实际延时:[1 + (501 + 2)×199] = 1000.98ms,,DELAY:MOV R2,#CTS ;T = 1us,,LOOPS:MOV B,#CTR ;T = 1us,,LOOPR:DJNZ B,LOOPR ;2T = 2us,,DJNZ R2,LOOPS ;2T = 2us,,END,,,例 7,10 秒延时程序。

      ,,延时程序与 MCS - 51 执行指令的时间有关, 如果使用 6 MHz晶振, 一个机器周期为 2 μs, 计算出一条指令以至一个循环所需要的执行时间, 给出相应的循环次数, 便能达到延时的目的10 秒延时程序如下: ,,DELAY: MOV R5, #100,,DEL0: MOV R6, #200,,DEL1: MOV R7, #248,,DEL2: DJNZ R7, DEL2,,DJNZ R6, DEL1,,DJNZ R5, DEL0,,RET,,上例程序中采用了多重循环程序, 即在一个循环体中又包含了其它的循环程序, 这种方式是实现延时程序的常用方法 使用多重循环时, 必须注意: ,,(1) 循环嵌套, 必须层次分明, 不允许产生内外层循环交叉2) 外循环可以一层层向内循环进入, 结束时由里往外一层层退出 ,,(3) 内循环可以直接转入外循环, 实现一个循环由多个条件控制的循环结构方式例 8,在外部 RAM中, BLOCK开始的单元中有一无符号数据块, 其个数为 LEN个字节试将这些无符号数按递减次序重新排列, 并存入原存储区。

      ORG 1000H ,,START: MOV DPTR, #BLOCK; 置地址指针,,MOV P2, DPH ; P2作地址指针高字节,,MOV R7, #LEN ; 置外循环计数初值,,DEC R7 ; 比较与交换 n-1次,,LOOP0: CLR F0 ; 交换标志清 0,,MOV R0, DPL; ,,MOV R1, DPL ; 置相邻两数地址指针低字节,,INC R1 ,,MOV R6, R7 ; 置内循环计数器初值,,LOOP1: MOVX A, @R0 ; 取数,,MOV B, A ; 暂存,,MOVX A, @R1 ; 取下一个数,,CJNE A, B, NEXT; 相邻两数比较, 不等转,,SJMP NOCHA ; 相等不交换,,NEXT: JC NOCHA; Cy =1, 则前者大于后者, 不必交换,,SETB F0 ; 否则, 置交换标志,,MOVX @R0, A ;,,XCH A, B ; 两数交换, 大者在前, 小者在后,,MOVX @R1, A ;,,NOCHA: INC R0,,INC R1; 修改指针,,DJNZ R6, LOOP1 ; 内循环未完, 则继续,,JNB F0, EXIT ; 若从未交换, 则结束,,DJNZ R7, LOOP0; 外循环未完, 则继续,,EXIT: RET,,图 4.5,,,例 9,设某系统的模数转换器是ADC0809, 它的转换结束信号 EOC连接到8031 的P1.7端, 当 EOC的状态由低变高时, 则结束循环等待, 并读取转换值, 其程序如下:,,START: MOV DPTR, #addr ; 0809端口地址送DPTR,,MOV A, #00H ; 启动0809转换,,MOVX @DPTR, A,,LOOP: JNB P1.7, LOOP; 检测P1.7状态, 判是否转换结束,, MOVXCA, @DPTR; 读取转换结果,…,,,例10,在内部 RAM中从 50H单元开始的连续单元依次存放了一串字符, 该字符串以回车符为结束标志, 要求测试该字符串的长度。

      程序如下: ,,START: MOV R2, #0FFH ,,MOV R0, #4FH ; 数据指针R0置初值,,LOOP: INC R0,,INC R2,,CJNE @R0, #0DH, LOOP,,RET,,4.2.4 散转程序设计,散转程序是分支程序的一种, 它可根据运算结果或输入数据将程序转入不同的分支MCS - 51 指令系统中有一条跳转指令JMP@A+DPTR, 用它可以很容易地实现散转功能该指令把累加器的 8 位无符号数与 16 位数据指针的内容相加, 并把相加的结果装入程序计数器PC, 控制程序转向目标地址去执行此指令的特点在于, 转移的目标地址不是在编程或汇编时预先确定的, 而是在程序运行过程中动态地确定的目标地址是以数据指针 DPTR的内容为起始的 256 字节范围内的指定地址, 即由 DPTR的内容决定分支转移程序的首地址, 由累加器 A的内容来动态选择其中的某一个分支转移程序例 11,根据工作寄存器R0 内容的不同, 使程序转入相应的分支 ,,(R0)=0 对应的分支程序标号为PR0; ,,(R0)=1 对应的分支程序标号为PR1; ,,,,(R0)=N 对应的分支程序标号为PRN。

      …,,程序如下: ,,LP0: MOV DPTR, #TAB ; 取表头地址,,MOV A, R0 ,,ADD A, R0 ; R0内容乘以2,,JNC LP1 ; 无进位转移,,INC DPH ; 加进位位,,LP1: JMP @A+DPTR; 跳至散转表中相应位置,,,,TAB: AJMP PR0,,AJMP PR1,,,,AJMP PRN,…,…,,本例程序仅适用于散转表首地址 TAB和处理程序入口地址 PR0, PR1, …, PRN在同一个 2 KB范围的存储区内的情形若超出 2 KB范围可在分支程序入口处安排一条长跳转指令, 可采用如下程序:,MOV DPTR, #TAB,,MOV A, R0 ,,MOV B, #03H ; 长跳转指令占 3 个字节,,MUL AB,,XCH A, B,,ADD A, DPH,,MOV DPH, A,,XCH A, B,,JMP @A+DPTR; 跳至散转表中相应的位置,,,,TAB: LJMP PR0; 跳至不同的分支,,LJMP PR1,,,,LJMP PRN,…,…,,4.2.5 子程序和参数传递,,一、 子程序的概念,,,通常把这些基本操作功能编制为程序段作为独立的子程序, 以供不同程序或同一程序反复调用。

      在程序中需要执行这种操作的地方放置一条调用指令, 当程序执行到调用指令, 就转到子程序中完成规定的操作, 并返回到原来的程序继 续执行下去二、 子程序的调用,,调用子程序的指令有“ACALL”和“LCALL”, 执行调用指令时, 先将程序地址指针PC改变(“ACALL”加 2, “LCALL”加 3), 然后 PC值压入堆栈, 用新的地址值代替执行返回指令时, 再将 PC值弹出 ,,子程序调用中, 主程序应先把有关的参数存入约定的位置, 子程序在执行时, 可以从约定的位置取得参数, 当子程序执行完, 将得到的结果再存入约定的位置, 返回主程序后, 主程序可以从这些约定的位置上取得需要的结果, 这就是参数的传递例12,把内部RAM某一单元中一个字节的十六进制数转换成两位ASCII码, 结果存放在内部RAM的连续两个单元中假设一个字节的十六进制数在内部 RAM 40H单元, 而结果存入 50H#, 51H单元, 可以用堆栈进行参数传递, 程序如下:,MAIN: MOV R1, #50H ; R1 为存结果的指针,,MOV A, 40H ; A为需转换的十六进制数,,SWAP A ; 先转换高位半字,,PUSH ACC ; 压栈,,LCALL HEASC ; 调用将低半字节的内容转换;,,成ASCII码子程序HEASC,,POP ACC,,MOV @R1, A ; 存高半字节转换结果,,INC R1,,PUSH 40H,,LCALL HEASC,,,POP ACC,,MOV @R1, A ; 存低半字节转换结果,,END,,HEASC: MOV R0, SP ,,DEC R0,,DEC R0 ; R0 指向十六进制数参数地址,,XCH A, @R0 ; 取被转换参数,,ANL A, #0FH ; 保留低半字节,,ADD A, #2 ; 修改 A值,,MOVC A, @A+PC ; 查表,,XCH A, @R0; 结果送回堆栈,,RET,,TAB: DB 30H, 31H, 32H, …,,4.2.6 查表程序设计,查表程序是一种常用程序, 它广泛使用于 LED显示控制、 打印机打印控制、数据补偿、数值计算、转换等功能程序中, 这类程序具有简单、执行速度快等特点。

      ,,所谓查表法, 就是预先将满足一定精度要求的表示变量与函数值之间关系的一张表求出, 然后把这张表存于单片机的程序存储器中, 这时自变量值为单元地址, 相应的函数值为该地址单元中的内容查表, 就是根据变量 X在表格中查找对应的函数值 Y, 使 Y=f(X)MCS - 51指令系统中, 有两条查表指令: ,,MOVC A, @A+PC,,MOVC A, @A+DPTR,,例 13,一个十六进制数存放在内部 RAM 的 HEX单元的低 4 位中, 将其转换成ASCII码并送回 HEX单元 ,,十六进制 0~9的ASCII码为 30H~39H, A~F的ASCII码为41H~46H, ASCII码表格的首地址为ASCTAB编程如下:,ORG 1000H ,,HEXASC: MOV A, HEX,,ANL A, # 0FH,,ADD A, # 3; 修改指针,,MOVC A, @A+PC,,MOV HEX, A,,RET,,ASCTAB: DB 30H, 31H, 32H, 33H, 34H,,DB 35H, 36H, 37H, 38H, 39H,,DB 41H, 42H, 43H, 44H, 45H,,DB 46H,,在这个程序中, 查表指令MOVC A, @A+PC到表格首地址有两条指令, 占用 3 个字节地址空间, 故修改指针应加 3。

      例 14,设有一个巡回检测报警装置, 需对 96 路输入进行控制, 每路有一个额定的最大值, 是双字节数当检测量大于该路对应的最大值时, 就越限报警假设R2 为保存检测路数的寄存器, 其对应的最大额定值存放于 31H和 32H单元中 查找最大额定值的程序如下:,FMAX: MOV A, R2 ,,ADD A, R2 ; 表中一个额定值为2个字节,,MOV 31H, A,,MOV DPTR, #TAB ; 表首址,,MOVC A, @A+DPTR; 查表读取第一个字节,,XCH A, 31H ; 第一个字节内容存入31H,,INC DPTR,,MOVC A, @A+DPTR; 查表读取第二个字节,,MOV 32H, A ; 第二字节的内容存入32H,,TAB: DW 1230H, 1450H, ...,,DW 2230H, 2440H, ...,,DW 3120H, 3300H, ...,,,例 15,在一个温度检测系统中, 温度模拟信号由 10 位A/D输入将A/D结果转换为对应温度值, 可采用查表方法实现 先由实验测试出整个温度量程范围内的A/D转换结果, 把A/D转换结果000H~3FFH所对应的温度值组织为一个表存储在程序存储器中, 那么就可以根据检测到的模拟量的 A/D转换值查找出相应的温度值。

      ,,设测得的A/D转换结果已存入 20H#, 21H单元中(高位字节在20H中, 低位字节在21H中), 查表得到的温度值存放在22H#,23H单元(高位字节在 22H中, 低位字节在23H中)程序如下: ,,FTMP: MOV DPTR, #TAB ; DPTR←表首地址,,MOVA, 21H ; (20H)(21H)×2,,CLRC,,RLCA,,MOV21H, A,,MOVA, 20H,,RLCA,,MOV20H, A,,MOVA, 21H ; 表首地址+偏移量 ,,ADDC A, DPL,,MOVDPL, A,,MOVA, 20H,,ADDC A, DPH,,MOVDPH, A,,CLR A,,MOVC A, @A+DPTR; 查表得温度值高位字节,,MOV22H, A,,CLRA,,INCDPTR,,MOVC A, @A+DPTR; 查表得温度值低位字节,,MOV23H, A,,RET,,TAB: DW …,,4.2.7 数制转换,例 16,将一个字节二进制数转换成 3 位非压缩型BCD码。

      设一个字节二进制数在内部RAM 40H单元, 转换结果放入内部 RAM 50H#, 51H, 52H单元中(高位在前), 程序如下:,HEXBCD: MOV A, 40H,,MOV B, #100,,DIV AB,,MOV 50H, A,,MOV A, #10,,XCH A, B,,DIV AB,,MOV 51H, A,,MOV 52H, B,,RET,,例 17,设 4 位BCD码依次存放在内存 RAM中 40H~43H单元的低4 位, 高 4 位都为 0, 要求将其转换为二进制数, 结果存入 R2R3 中 ,,一个十进制数可表示为: ,,Dn×10,n,+D,n-1,×10,n-1,+… + D,0,×10,0,,,=(…((D,n,×10+D,n-1,)×10+D,n-2,)×10+…)+D,0,,,当n=3时, 上式可表示为: ,,((D,3,×10+D,2,)×10+D,1,)×10+D,0,,,BCDHEX: MOV R0, #40H ; R0指向最高位地址,,MOV R1, #03 ; 计数值送R1,,MOV R2, #0 ; 存放结果的高位清零,,MOV A, @R0,,MOV R3, A,,LOOP: MOV A, R3,,MOV B, #10,,MULAB,,MOV R3, A ; (R3)×10 的低 8 位送R3,,MOV A, B,,XCHA, R2 ; (R3)×10的高 8 位暂存R2,,MOVB, #10,,MULAB,,ADD A, R2,,MOVR2, A ; R2×10+( R3×10)高 8 位送R2,,INCR0 ; 取下一个 BCD数,,MOVA, R3,,ADDA, @R0,,MOVR3, A,,MOVA, R2,,ADDC A, #0 ; 加低字节来的进位,,MOVR2, A,,DJNZ R1, LOOP,,RET,,4.2.8 运算程序,一、 加、 减法程序,,例 18,将40H开始存放的 10 个字节的数与 50H开始存放的10 个字节的数相减(假设被减数大于减数)。

      ,,设被减数指针为 R0, 减数指针为 R1, 差数放回被减数单元, R5 存放字节个数, 则程序如下:,,SUB: MOV R0, #40H,,MOV R1, #50H,,MOV R5, #10,,CLR C,,SUB1: MOV A, @R0,,SUBB A, @R1,,MOV @R0, A,,INC R0,,INC R1,,DJNZ R5, SUB1,,RET,,,二、 乘法运算程序,,在计算机中, 常将乘法采用移位和加法来实现 ,,例19,将(R2R3)和(R6R7)中双字节无符号数相乘, 结果存入 R4R5R6R7 ,,此乘法可以采用部分积右移的方法来实现, 其程序框图如图 4.6 所示, 程序如下:,NMUL: MOV R4, #0 ; 初始化,,MOV R5, #0,,CLR C,,MOV R0, #16,,NMUL1: MOV A, R4 ; CyR4R5R6R7右移一位,,RRC A,,MOV R4, A,,MOV A, R5,,RRC A,,MOV R5, A,,MOV A, R6,,RRC A,,MOV R6, A,,MOV A, R7,,RRC,,MOV R7, A,,JNC NMUL2; C为移出乘数的最低位,,MOV A, R5 ; (R4R5)+(R6F7)→(R4R5),,ADD A, R3,,MOV R5, A,,MOV A, R4,,ADDC A, R2,,MOV R4, A,,NMUL2: DJNZR0, NMUL1; 循环16位,,MOV A, R4; 最后结果再移一位,,RRC A,,MOV R4, A,,MOV A, R5,,RRC A,,MOV R5, A,,MOV A, R6,,RRC A,,MOV R6, A,,MOV A, R7,,RRC A,,MOV R7, A,,RET,,图4.6 NMUL程序框图,,,,例 20,假定被乘数在(R4R3)中, 乘数放在R2中, 乘积放在R7R6和R5中。

      ,,MCS - 51 中有 8 位数的乘法指令MUL, 用它来实现多字节乘法时, 可表示为,,(R4R3)×(R2) =[(R4)×2,8,+(R3)]×(R2),,=(R4)×(R2)×2,8,+(R3)×(R2),,其中(R4)×(R2)和(R3)×(R2)都是可直接用MUL指令来实现, 而乘以2,8,意味着左移 8 位由此可编写如下程序:,,NMUL1: MOV A, R2 ,,MOV B, R3,,MUL AB ; (R3)×(R2),,MOV R5, A ; 积的低位送R5,,MOV R6, B ; 积的高位送R6,,MOV A, R2,,MOV B, R4,,MUL AB ; (R4)×(R2),,ADD A, R6 ; (R3)×(R2)的高位加(R4)×(R2)的低位,,MOV A, B,,ADDC A, #00H ; (R4)×(R2)的高位加Cy,,MOV R7, A ; 结果送R7,,RET,,三、 除法运算程序,,,除法是乘法的逆运算, 用移位、 相减的方法来完成 首先比较被除数的高位字与除数, 如被除数高位大于除数, 则商为1, 并从被除数中减去除数, 形成一个部分余数; 否则商位为 0, 不执行减法。

      然后把新的部分余数左移一位, 并与除数再次进行比较循环此步骤, 直到被除数的所有位都处理完为止,一般商的字长为 n, 则需循环n次 一般计算机中, 被除数均为双倍位, 即如果除数和商为双字节, 则被除数为四字节如果在除法中发生商大于规定字节, 称为溢出 在进行除法前, 应该检查是否会产生溢出一般可在进行除法前, 先比较被除数的高位与除数, 如被除数高位大于除数, 则溢出, 置溢出标志, 不执行除法图 4.7 除法程序的流程,,,例 21,将(R4R5R6R7)除以(R2R3), 商放在(R6R7)中, 余数放在(R4R5)中NDIV: MOV A, R5 ; 判商是否产生溢出,,CLR C,,SUBB A, R3,,MOV A, R4,,SUBB A, R2,,JNC NDIV1 ; 溢出, 转溢出处理,,MOV B, #16; 无溢出, 执行除法,,NDIV2: CLR C ; 被除数左移一位, 低位送 0,,MOV A, R7,,RLC A,,MOV R7, A,,MOV A, R6,,RLC A,,MOV R6, A,,MOV A, R5,,RLC A,,MOV R5, A,,XCH A, R4,,RLC A,,XCH A, R4,,MOV F0, C ; 保护移出的最高位,,CLR C,,SUBB A, R3 ; 部分余数与除数比较,,MOV R1, A,,MOV A, R4,,SUBB A, R2,,JB F0, NDIV3; 移出的高位为 1, 肯定够减,,JC NDIV4 ; 否则, (Cy) = 0才够减,,NDIV3: MOV R4, A ; 回送减法结果,,MOV A, R1,,MOV R5, A,,INC R7 ; 商上1,,NDIV4: DJNZ B, NDIV2; 循环次数减 1 ,若不为零则循环,,CLR F0 ; 正常执行无溢出 F0 = 0,,RET,,NDIV1: SETB F0 ; 溢出F0=1,,RET,,。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.