文档详情

第三章MCS51单片机的汇编语言程序设计(8学时)课件

汽***
实名认证
店铺
PPT
304.38KB
约66页
文档ID:588518979
第三章MCS51单片机的汇编语言程序设计(8学时)课件_第1页
1/66

步骤:1.编制要解决的问题的程序框图;2.确定数据结构、算法、工作单元、变量等;3.按照已编制的程序框图编写源程序;4.调试源程序,直至实现预定的功能第三章第三章 汇编语言程序设计汇编语言程序设计 1 12 21 1步骤:第三章  汇编语言程序设计 121 3.1 简单程序设计简单程序设计 例例 1  两个无符号双字节数相加         设被加数存放于内部RAM的40H(高位字节), 41H(低位字节), 加数存放于50H(高位字节), 51H(低位字节), 和数存入  40H和41H单元中 12122 23.1  简单程序设计         例 1  两个无符号 程序如下:    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 12123 3程序如下: 123 3.2 分支程序设计分支程序设计 图  4.1 分支结构框图(a) 单分支流程; (b) 多分支流程 12124 43.2  分支程序设计 图  4.1 分支结构框图124        例例 4   比较两个无符号数的大小。

       设外部 RAM 的存储单元  ST1和  ST2中存放两个不带符号的二进制数, 找出其中的大数存入外部 RAM 中的   ST3单元中 图  3.3 12125 5       例 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 12126 6程序如下:126 SUBB  A, R2; 两数比较JNC  BIG1 ; 若第二个数大, 则转XCH  A, R2; 第一个数大BIG0: MOV  DPTR, #ST3 MOVX  @DPTR, A ; 存大数RETBIG1: MOVX  A, @DPTR; 第二个数大(ADD   A,R2)           SJMP  BIG012127 7SUBB  A, R2; 两数比较127        循环程序一般由四个主要部分组成:        (1) 初始化部分: 为循环程序做准备, 如规定循环次数、 给各变量和地址指针预置初值。

        (2) 处理部分: 为反复执行的程序段, 是循环程序的实体, 也是循环程序的主体        (3) 循环控制部分: 这部分的作用是修改循环变量和控制变量, 并判断循环是否结束, 直到符合结束条件时, 跳出循环为止        (4) 结束部分: 这部分主要是对循环程序的结果进行分析、 处理和存放 3.3 循环程序设计循环程序设计 12128 8       循环程序一般由四个主要部分组成: 3.3 循 图 4.4 12129 9图 4.4 129   1.已知循环次数的循环程序设计      例例 5 工作单元清零         在应用系统程序设计时, 有时经常需要将存储器中各部分地址单元作为工作单元, 存放程序执行的中间值或执行结果, 工作单元清零工作常常放在程序的初始化部分中        设有50个工作单元, 其首址为外部存储器8000H单元, 则其工作单元清零程序如下: 12121 10 0  1.已知循环次数的循环程序设计1210  CLEAR:  CLR  A                          MOV  DPTR, #8000H   ; 工作单元首址送指针             MOV  R2, #50 ; 置循环次数CLEAR1: MOVX   @DPTR, A                 INC   DPTR   ; 修改指针                 DJNZ  R2, CLEAR1; 控制循环                 RET CLEAR: CLR A MOV DPTR,#8000H MOV R2,#50CLR2: DJNZ R2,CLR1 RETCLR1: MOVX @DPTR,A INC DPTR SJMP CLR2#50+112121 11 1 CLEAR:  CLR  A         CLEAR 例例 6  设在内部 RAM的BLOCK单元开始处有长度为  LEN个的无符号数据块, 试编一个求和程序, 并将和存入内部 RAM的  SUM单元(设和不超过  8 位)。

   BLOCK    EQU    20H          LEN     EQU     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 12121 12 2        例 6  设在内部 RAM的BLOCK单元开 2.未知循环次数的循环程序 需根据判断循环条件的成立与否,或用建立标志的方法,控制循环程序的结束例7:计算字符串长度 设在内部 RAM的BLOCK单元开始存有一个字符串, 请统计字符串的长度存内部 RAM的 SUM单元。

已知字符串以回车符为结束标志 1 12 21 13 32.未知循环次数的循环程序       需根据判断循环条件的 程序如下:     START:  MOV  SUM, #0FFH                         MOV  R0, #BLOCK-1  ; 数据指针R0置初值    LOOP:    INC  R0                    INC  SUM                   CJNE  @R0, #0DH, LOOP                   RET START:MOV SUM,#00H MOV R0,#BLOCKLOOP: CJNE @R0,#0DH,LOP1 RETLOP1: INC R0 INC SUM SJMP LOOP 12121 14 4程序如下: START:MOV  SUM,#00H1214 二、二、 多重循环多重循环        多重循环程序, 即在一个循环体中又包含了其它的循环程序, 这种方式是实现延时程序的常用方法。

 使用多重循环时, 必须注意:        (1) 循环嵌套, 必须层次分明, 不允许产生内外层循环交叉        (2) 外循环可以一层层向内循环进入, 结束时由里往外一层层退出        (3) 内循环可以直接转入外循环, 实现一个循环由多个条件控制的循环结构方式 12121 15 5 二、 多重循环        多重循环程序, 即在一个循环 例例 10:  10 秒延时程序        延时程序与指令的执行时间有关, 如果使用 11.0592MHz晶振, 一个机器周期为 1.085 μs, 计算出一条指令以至一个循环所需要的执行时间, 给出相应的循环次数, 便能达到延时的目的1秒延时程序如何写? 12121 16 6        例 10:  10 秒延时程序1216               ORG  0040H     ;1秒延时程序delay1s: mov  r1 , #46     ;立即数46送寄存器R1     del1:  mov  r2 , #100   ;立即数100送寄存器R2      del2: mov  r3 , #100   ;立即数100送寄存器R3      del0: djnz  r3 , del0    ;寄存器R3中的内容减1,不为零转移到当前指令               djnz  r2 , del2    ;寄存器R2中的内容减1,不为零转移到del1               djnz  r1 , del1    ;寄存器R1中的内容减1,不为零转移到del0               end{{[(Tdjnzr3×100)+Tmovr3+Tdjnzr2] ×100+ Tmovr2+Tdjnzr1}×46+Tmovr1}×Tm式中Tdjnzr3是执行指令djnz的机器周期数,Tmovr3是执行指令mov的机器周期数。

将Tdjnzr3= Tdjnzr2= Tdjnzr1=2,Tmovr3= Tmovr2= Tmovr1=1,Tm=1.085 μs代入上式,算得1.013秒1 12 21 17 7              ORG  0040H     ; 例例 11 :冒泡程序: 在外部 RAM中, BLOCK开始的单元中有一无符号数据块, 其个数为LEN个字节试将这些无符号数按递减次序重新排列, 并存入原存储区 36512351263125612356 要用双重循环来实现,内环完成相邻数据的两两比较,外环控制内循环的次数12121 18 8       例 11 :冒泡程序: 在外部 RAM中, B 图  4.512121 19 9图  4.51219                  ORG  0000H         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 ; 置相邻两数地址指针低字节12122 20 0                 ORG  0000H                   INC  R1                  MOV  A, R7    ; 置内循环计数器初值                MOV   R6,A  LOOP1: MOVX  A, @R0 ; 取数               MOV  B, A           ; 暂存               MOVX  A, @R1   ; 取下一个数               CJNE  A, B, NEXT; 相邻两数比较, 不等转               SJMP  NOCHA      ; 相等不交换 12122 21 11221   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 12122 22 2  NEXT:  JC    NOCHA    ; Cy = 3.4 散转程序设计散转程序设计         散转程序是分支程序的一种, 它可根据运算结果或输入数据将程序转入不同的分支。

MCS - 51 指令系统中有一条跳转指令JMP  @A+DPTR, 用它可以很容易地实现散转功能该指令把累加器的  8 位无符号数与 16 位数据指针的内容相加, 并把相加的结果装入程序计数器PC, 控制程序转向目标地址去执行此指令的特点在于, 转移的目标地址不是在编程或汇编时预先确定的, 而是在程序运行过程中动态地确定的目标地址是以数据指针 DPTR的内容为起始的 256 字节范围内的指定地址, 即由 DPTR的内容决定分支转移程序的首地址, 由累加器  A的内容来动态选择其中的某一个分支转移程序 12122 23 33.4  散转程序设计         散转程序是分支程序 例例 11  一应用系统设有N个功能键,分别用键号0~(N-1)表示,已知读出的键号存放在R0中,请根据R0的内容转入相应的功能程序         (R0)=0   对应的分支程序标号为PKEY0;         (R0)=1   对应的分支程序标号为PKEY1;    ………        (R0)=N-1   对应的分支程序标号为PKEYN-1 …12122 24 4        例 11  一应用系统设有N个功能键,分别用 方法1:用长转移指令表。

程序如下: LP0:    MOV  DPTR, #TAB   ; 取表头地址            MOV  A, R0             MOV  B, #03H   ; 长跳转指令占 3 个字节            MUL  AB            XCH  A, B            ADD  A, DPH;DPTR高8位调整,低8位                                            在散转指令过程进行相加           MOV  DPH, A           XCH  A, B LP1:   JMP  @A+DPTR; 跳至散转表中相应位置TAB:  LJMP    PKEY0            LJMP    PKEYN-1 ……12122 25 5方法1:用长转移指令表……1225 方法方法2 2:用转移地址表:用转移地址表程序如下:程序如下:MOV DPTR,#TABMOV DPTR,#TAB MOV A,R0 MOV A,R0 ADD A,R0 ADD A,R0 ;;R0*2R0*2 MOV B,A MOV B,A MOVC A,@A+DPTR MOVC A,@A+DPTR ;入口高;入口高8 8位位 XCH A,B XCH A,B INC A INC A MOVC A,@A+DPTR MOVC A,@A+DPTR ;入口低;入口低8 8位位 MOV DPL,A MOV DPL,A MOV DPH,B MOV DPH,B CLR A CLR A JMP @A+DPTR JMP @A+DPTRPUSH      ACC ;低8位进栈PUSH      B       ;高8位进栈RET       ;地址退栈至PC,指针恢复TAB:    DW     PKEY0, PKEY1, ....    PKEYN-1PKEY0(H)PKEY0(H)PKEY0(L)PKEY0(L)PKEY1(H)PKEY1(H)PKEY1(L)PKEY1(L)PKEY2(H)PKEY2(H)PKEY2(L)PKEY2(L)PKEY3(H)PKEY3(H)PKEY3(L)PKEY3(L)............PKEYN-1(H)PKEYN-1(H)PKEYN-1(L)PKEYN-1(L)... ...... ...TAB:PKEY0:1 12 22 26 6方法2:用转移地址表程序如下:MOV    DPTR,#TA 3.5 子程序和参数传递子程序和参数传递 一、一、 子程序的概念子程序的概念        通常把这些基本操作功能编制为程序段作为独立的子程序, 以供不同程序或同一程序反复调用。

在程序中需要执行这种操作的地方放置一条调用指令, 当程序执行到调用指令, 就转到子程序中完成规定的操作, 并返回到原来的程序继续执行下去 主子12122 27 73.5 子程序和参数传递 一、 子程序的概念主子1227 二、二、 子程序的调用子程序的调用        调用子程序的指令有“ACALL”和“LCALL”, 执行调用指令时,  先将程序地址指针PC改变(“ACALL”加    2, “LCALL”加 3), 然后 PC值压入堆栈, 用新的地址值代替执行返回指令时, 再将 PC值弹出         子程序调用中, 主程序应先把有关的参数存入约定的位置, 子程序在执行时, 可以从约定的位置取得参数, 当子程序执行完, 将得到的结果再存入约定的位置, 返回主程序后, 主程序可以从这些约定的位置上取得需要的结果, 这就是参数的传递 12122 28 8二、 子程序的调用1228 1.用寄存器传递参数例:求平方计算例:求平方计算 SQU SQU:: MOV B MOV B,,A A MUL AB MUL AB RET RET 如要完成如要完成30H30H、、31H31H两数的平方和存两数的平方和存32H33H 32H33H MOV A,30HMOV A,30HLCALL SQULCALL SQUMOV 32H,BMOV 32H,BMOV 33H,AMOV 33H,AMOV A,31HMOV A,31HLCALL SQULCALL SQU ADD A,33HADD A,33HMOV 33H,AMOV 33H,AMOV A,BMOV A,B ADDC A,32H ADDC A,32HMOV 32H,AMOV 32H,A1 12 22 29 91.用寄存器传递参数例:求平方计算。

MOV    A,30H 2.用指针传递参数例:对内例:对内RAMRAM多个单元清零多个单元清零 CLEAR CLEAR::CLR ACLR A MOV @R0,A MOV @R0,A INC R0 INC R0 DJNZ R2,CLEAR DJNZ R2,CLEAR RET RET 比如要对比如要对50H50H单元开始的单元开始的1010个单元清零个单元清零MAIN: MOV R0,#50HMAIN: MOV R0,#50H MOV R2,#10 MOV R2,#10 LCALL CLEAR LCALL CLEAR ……. …….1 12 23 30 02.用指针传递参数例:对内RAM多个单元清零。

1230 例例12 把内部RAM某一单元中一个字节的十六进制数转换成两位ASCII码, 结果存放在内部RAM的连续两个单元中       假设一个字节的十六进制数在内部  RAM   40H单元, 而结果存入  50H, 51H单元, 可以用堆栈进行参数传递: 内RAM0BH0AH09H08H07HSPLCALL CHHASPPC.LPC.HCHHA: ...... RETSPSPSPPC.HPC.LPUSH ACCPC.HPC.LACC3.用堆栈传递参数12123 31 1        例12 把内部RAM某一单元中一个字节的十六 HEASC:    MOV  R0, SP      DEC  R0   DEC  R0             ; R0 指向十六进制数参数地址   XCH  A, @R0           ; 取被转换参数   ANL  A, #0FH        ; 保留低半字节   ADD  A, #?            ; 修改  A值   MOVC  A, @A+PC   ; 查表  XCH  A, @R0            ; 结果送回堆栈  RET  TAB:     DB  30H, 31H, 32H, … 2 ;增加MOVC指令首地址与表头地址之间的单元数12123 32 2HEASC: 2         ;增加MOVC指令首地址与 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  ; 存低半字节转换结果   SJMP       $1 12 23 33 3MAIN:  1233 3.6 查表程序设计查表程序设计         查表程序是一种常用程序, 它广泛使用于  LED显示控制、 打印机打印控制、数据补偿、数值计算、转换等功能程序中, 这类程序具有简单、执行速度快等特点。

         所谓查表法, 就是预先将满足一定精度要求的表示变量与函数值之间关系的一张表求出, 然后把这张表存于单片机的程序存储器中, 这时自变量值为单元地址, 相应的函数值为该地址单元中的内容查表, 就是根据变量  X在表格中查找对应的函数值  Y, 使   Y=f(X) 12123 34 43.6  查表程序设计         查表程序是一种常用程 MCS - 51指令系统中, 有两条查表指令:     MOVC  A, @A+PC    MOVC  A, @A+DPTR 12123 35 5MCS - 51指令系统中, 有两条查表指令: 1235 例例 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 12123 36 6        例 13  一个十六进制数存放在内部 RAM 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。

 12123 37 7ASCTAB: DB  30H, 31H, 32H, 33H 例例 14 设有一个巡回检测报警装置, 需对 96 路输入进行控制, 每路有一个额定的最大值, 是双字节数当检测量大于该路对应的最大值时, 就越限报警假设R2 为保存检测路数的寄存器, 其对应的最大额定值存放于 31H和 32H单元中 查找最大额定值的程序如下:  FMAX:  MOV  A, R2           ADD  A, R2   ; 表中一个额定值为2个字节    MOV  31H, A    MOV  DPTR, #TAB ; 表首址 12123 38 8        例 14 设有一个巡回检测报警装置, 需对  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, ... 12123 39 9MOVC  A, @A+DPTR; 查表读取第一个字节1        例例 15  在一个温度检测系统中, 温度模拟信号由 10 位A/D输入。

将A/D结果转换为对应温度值, 可采用查表方法实现 先由实验测试出整个温度量程范围内的A/D转换结果, 把A/D转换结果000H~3FFH所对应的温度值组织为一个表存储在程序存储器中, 那么就可以根据检测到的模拟量的   A/D转换值查找出相应的温度值        设测得的A/D转换结果已存入  20H#,  21H单元中(高位字节在20H中, 低位字节在21H中), 查表得到的温度值存放在22H,23H单元(高位字节在 22H中, 低位字节在23H中) 12124 40 0       例 15  在一个温度检测系统中, 温度模拟信 程序如下:  FTMP: MOV   DPTR, #TAB       ; DPTR←表首地址 MOV  A, 21H   ; (20H)(21H)×2CLR  CRLC  AMOV  21H, AMOV  A, 20HRLC  AMOV  20H, AMOV  A, 21H   ; 表首地址+偏移量 ADDC  A, DPLMOV  DPL, A12124 41 1程序如下: 1241 MOV       A, 20HADDC    A, DPHMOV      DPH, ACLR       AMOVC   A, @A+DPTR; 查表得温度值高位字节MOV     22H, ACLR      AINC     DPTRMOVC  A, @A+DPTR; 查表得温度值低位字节MOV   23H, ARETTAB:   DW … 12124 42 2MOV       A, 20H1242 3.7 数制转换数制转换 1、、十六进制到十进制的转换。

例例 16 :将一个字节二进制数转换成 3 位非压缩型BCD码         设一个字节二进制数在内部RAM 40H单元, 转换结果放入内部   RAM  50H, 51H, 52H单元中(高位在前), 程序如下:  在应用系统中,由于人们日常生活中用的是十进制数,而计算机中用的是十六进制数,所以应用系统中一定有数制之间的转换,如十进制到十六进制、十六进制到十进制、十进制到ASCII、十进制到段选码等的转换12124 43 33.7 数制转换         1、十六进制到十进制的转换 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 1 12 24 44 4HEXBCD: 1244 例:多字节二进制数转换成十进制数 将内RAM 30H31H中的16位二进制数转换成十进制数存在32H33H34H中。

1100110B=(((((1*2+1)*2+0)*2+0)*2+1)*2+1)*2+0=((((((00*2+1)*2+1)*2+0)*2+0)*2+1)*2+1)*2+0 所以每一个包括内都是完成一个数乘2再加一位二进制数的过程,乘2可以用自身相加方式来实现 ,加一位二进制数可以ADDC加进位的方式实现,加的过程用DA A进行十进制数调整,则是式的计算过程可实现二进制数到十进制数的转换二进制数到十进制数的转换1 12 24 45 5例:多字节二进制数转换成十进制数        将内RAM  CHHDCHHD:: MOV 32H,#00H MOV 32H,#00H MOV 33H,#00H MOV 33H,#00H MOV 34H,#00H MOV 34H,#00H MOV R2,#16 MOV R2,#16LOOP: MOV A,31HLOOP: MOV A,31H RLC A RLC A MOV 31H,A MOV 31H,A MOV A,30H MOV A,30H RLC A RLC A MOV 30H,A MOV 30H,A MOV A,34H MOV A,34H ADDC A,34H ADDC A,34H 1 12 24 46 6CHHD:1246 DA ADA A MOV 34H,A MOV 34H,A MOV A,33H MOV A,33H ADDC A,33H ADDC A,33H DA A DA A MOV 33H,A MOV 33H,A MOV A,32H MOV A,32H ADDC A,32H ADDC A,32H DA A DA A MOV 32H,A MOV 32H,A DJNZ R2,LOOP DJNZ R2,LOOP RET RET 1 12 24 47 7             DA    A1247 例例 17  设 4 位BCD码依次存放在内存  RAM中 40H~43H单元的低4 位, 高 4 位都为 0, 要求将其转换为二进制数, 结果存入 R2R3 中。

         2、十进制到十六进制的转换一个十进制数可表示为:         Dn×10n +Dn-1×10n-1 +… + D0×100       =(…((Dn×10+Dn-1)×10+Dn-2)×10+…)+D0当n=3时, 上式可表示为:      (( D3×10+D2)×10+D1)×10+D0 12124 48 8        例 17  设 4 位BCD码依次存放在内存 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MUL     ABMOV     R3, A  ; (R3)×10 的低 8 位送R3MOV    A, BXCH     A, R2 ; (R3)×10的高 8 位暂存R2MOV     B, #10 12124 49 9BCDHEX:1249  MUL     AB ADD      A, R2 MOV      R2, A  ;  R2×10+( R3×10)高 8 位送R2 INC        R0  ; 取下一个  BCD数 MOV      A, R3 ADD      A, @R0 MOV     R3, A MOV      A, R2 ADDC    A, #0 ; 加低字节来的进位 MOV      R2, A DJNZ    R1, LOOP RET 12125 50 0 MUL     AB1250 3。

十六进制与ASCII码之间的相互转换4十六进制到段选码的转换1 12 25 51 13十六进制与ASCII码之间的相互转换4十六进制到段选码 3.8 运算程序运算程序 一、一、 加、加、 减法程序减法程序         例例 18  将40H开始存放的 10 个字节的数与  50H开始存放的10 个字节的数相减(假设被减数大于减数)        设被减数指针为 R0, 减数指针为 R1, 差数放回被减数单元, R5 存放字节个数, 则程序如下: 12125 52 23.8  运算程序 一、 加、 减法程序           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 12125 53 3 SUB:  MOV   R0, #40H1253 二、二、 乘法运算程序乘法运算程序         在计算机中, 常将乘法采用移位和加法来实现。

一般而言,设被乘数 x 、乘数 y 都是小于 1 的 n 位定点正数:         x = 0 . x1 x2 … xn ; y = 0 . y1 y2 … yn其乘积为x · y= x · ( 0.y1y2 … yn ) = x · ( y1 2 -1 + y2 2 -2 + … + yn 2 -n) = 2 -1( y1x + 2-1( y2 x + 2-1 (… + 2-1 ( yn-1 x + )…))令 zi 表示第 i 次部分积,则上式可写成如下递推公式:z0 = 0z1 = 2-1( ynx + z0) …zi = 2-1( yn-i+1x + zi-1)                    … zn = x·y = 2-1( y1x + zn-1)显然,欲求x·y,则需设置一个保存部分积的累加器乘法开始时,依此类推,直到求得y1x加上zn-1并右移1位得最后部分积,即得x·y显然,两个n位数相乘,需重复进行n次“加”及“右移”操作,才能得到最后乘积这就是实现原码一位乘法的规则1 12 25 54 4二、 乘法运算程序1254 例例19 将(R2R3)和(R6R7)中双字节无符号数相乘, 结果存入 R4R5R6R7。

          此乘法可以采用部分积右移的方法来实现, 其程序框图如图所示, 程序如下: NMUL:  MOV   R4, #0     ; 初始化   MOV  R5, #0   CLR  C   MOV  R0, #1612125 55 5例19 将(R2R3)和(R6R7)中双字节无符号数相乘,  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)+(R2R3)→(R4R5) 12125 56 6NMUL1: MOV A, R4  ; CyR4R5R6R7      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12125 57 7     ADD A, R31257  RRC A MOV R6, A MOV A, R7 RRC A MOV R7, A RET 12125 58 8 RRC A1258         例例 20 假定被乘数在(R4R3)中, 乘数放在R2中, 乘积放在R7R6和R5中。

 MCS - 51 中有 8 位数的乘法指令MUL, 用它来实现多字节乘法时, 可表示为    (R4R3)×(R2) =[(R4)×28+(R3)]×(R2)=(R4)×(R2)×28+(R3)×(R2)其中(R4)×(R2)和(R3)×(R2)都是可直接用MUL指令来实现, 而乘以28意味着左移 8 位由此可编写如下程序: 12125 59 9        例 20 假定被乘数在(R4R3)中, 乘数 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 12126 60 0NMUL1: MOV   A, R2    1260 三、三、 除法运算程序除法运算程序        除法是乘法的逆运算, 用移位、 相减的方法来完成。

 首先比较被除数的高位字与除数, 如被除数高位大于除数, 则商为1, 并从被除数中减去除数, 形成一个部分余数; 否则商位为 0, 不执行减法 然后把新的部分余数左移一位, 并与除数再次进行比较循环此步骤, 直到被除数的所有位都处理完为止,一般商的字长为  n, 则需循环n次 一般计算机中, 被除数均为双倍位, 即如果除数和商为双字节, 则被除数为四字节如果在除法中发生商大于规定字节, 称为溢出 在进行除法前, 应该检查是否会产生溢出一般可在进行除法前, 先比较被除数的高位与除数, 如被除数高位大于除数, 则溢出, 置溢出标志, 不执行除法 12126 61 1        三、 除法运算程序1261 图 4.7 除法程序的流程 12126 62 2图 4.7 除法程序的流程 1262 例例 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; 无溢出, 执行除法 12126 63 3          例 21  将(R4R5R6R7)除以( 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 12126 64 4NDIV2:  CLR C ; 被除数左移一位, 低位送 0  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 12126 65 5 MOV F0, C ; 保护移出的最高位1265  NDIV4:  DJNZ  B, NDIV2; 循环次数减 1 ,若不为零则循环    CLR  F0   ; 正常执行无溢出   F0 = 0    RET NDIV1: SETB  F0  ; 溢出F0=1               RET 12126 66 6 NDIV4:  DJNZ  B, NDIV2; 循环次数减 。

下载提示
相似文档
正为您匹配相似的精品文档