4.4 实用程序举例
description
Transcript of 4.4 实用程序举例
第 4章 汇编语言程序设计
主讲 ; 吴政江
4.4 实用程序举例
4.4.1 延时 在程序设计过程中,有时需要程序“等待”一会儿
再去处理某些事情,称之为延时。计算机延时实际就是让计算机反复执行一些空操作,这样就能起到拖延时间的作用。需要执行空操作次数的多少,取决于延时时间的长短。
第 4章 汇编语言程序设计
主讲 ; 吴政江
[ 例 4.15] 编写一段延时程序。 ORG 2000H ;周期数 × 执行次数 MOV R0 , #MT ; 1×1
DL : NOP ; 1×MT
NOP ; 1×MT
DJNZ R0 , DL ; 2×MT
第 4章 汇编语言程序设计
主讲 ; 吴政江
该程序的延时时间与系统所用的晶振和程序中每条指令的机器周期及其执行次数 MT 有关。设系统晶振为 12 MHz ,则可知一个机器周期为:
T=1s/(12×106 )×12=1 μs
延时时间 =T×(1×1+1×MT+1×MT+2×MT)
=1 μs×(1+MT+MT+2MT) (4-1)
第 4章 汇编语言程序设计
主讲 ; 吴政江
¿ª ʼ
R0¡ûÄÚÑ »·ÊýMI1
R1¡ûÍâÑ »·ÊýMI2
¿Õ²Ù×÷NOP
¿Õ²Ù×÷NOP
R1£ 1£½0 ?
R0£ 1£½0 ?
½á Êø
N
N
Y
Y
图 4-6 双重循环延时程序流程图
第 4章 汇编语言程序设计
主讲 ; 吴政江
[ 例 4.16] 用双重循环完成延时程序。程序如下:MOV R0 , #MT1 ; 1×1
DL1 : MOV R1 , #MT2 ; 1×MT1
DL2 : NOP ; 1×MT2×MT1
NOP ; 1×MT2×MT1
DJNZ R1 , DL2 ; 2×MT2×MT1
DJNZ R0 , DL1 ; 2×MT1
第 4章 汇编语言程序设计
主讲 ; 吴政江
设晶振仍为 12 MHz ,则上面程序的执行时间 T 为 :
T=1μs×(1+1×MT1+1×MT2×MT1+1×MT2×MT1+2× MT2×MT1
+2×MT1) (4-2)
4.4.2 代码转换 1 .十六进制到 ASCII 码的转换 [ 例 4.17] 将 20H 单元中的两个十六进制数转换成 ASCI
I 码,低 4 位的 ASCII 码保存在 21H 单元,高 4 位的 ASCII
码保存在 22H 单元。 由 ASCII 编码表可知,转换方法为:若十六进制数小于
10 ,则此数加 30H ,否则加上 37H 就可以将十六进制数转换成 ASCII 码。
第 4章 汇编语言程序设计
主讲 ; 吴政江
MOV A , 20H ; (20H)→A
ANL A , 0FH ;屏蔽高 4 位
ACALL CHANGE ;求低位十六进制数的 ASCII 码
MOV 21H , A ;保存低位十六进制数的 ASCII
码
MOV A , 20H ; (20H)→A
ANL A , #0F0H ;屏蔽低 4 位
SWAP A ;高位十六进制数送低 4 位
ACALL CHANGE ;求高位十六进制数的 ASCII 码
MOV 22H , A ;保存高位十六进制数的 ASCII
码
RET
第 4章 汇编语言程序设计
主讲 ; 吴政江
CHANGE: PUSH A ;操作数进栈保护 CLR C ;进位标志清零 SUBB A , #0AH ;与 10 比较 POP A ;取出操作数 JC NUM ;比 10 小转 NUM
ADD A , #07H ;大于等于 10 加 37
H
NUM : ADD A , #30H ;加 30H
RET
第 4章 汇编语言程序设计
主讲 ; 吴政江
2 .单字节二进制数转换为 BCD 数 [ 例 4.18] 已知 20H 单元存放一个二进制数,编程
将它转换为 BCD 数,百位送入 FIRST 单元的低 4 位,十位和个位分别送入 SECOND 单元的高 4 位和低 4 位。
本题只需将 20H 单元中的内容除以 100 ,得到的商就是百位 BCD 数,然后用余数除以 10 ,其结果中,商为十位 BCD 数,余数为个位 BCD 数。
第 4章 汇编语言程序设计
主讲 ; 吴政江
ORG 0100H
FIRST DATA 30H
SECOND DATA 31H
MOV A , 20H ;被除数送 A
MOV B , #64H ;除数 100 送 B
DIV AB ; A 除以 B
MOV FIRST , A ;百位 BCD 数送 FIRST
MOV A , B ;余数送 A
第 4章 汇编语言程序设计
主讲 ; 吴政江
MOV B , #0AH ;除数 10 送 B
DIV AB ; A 除以 B
SWAP A ;十位 BCD 数送高 4 位ORL A , B ;十位和个位 BCD 数组合
成一个字节MOV SECOND , A ;送入 SECOND 单
元SJMP $ ;结束END
第 4章 汇编语言程序设计
主讲 ; 吴政江
4.4.3 数据处理 1 .查询 [ 例 4.19] 在外部 RAM 1000H 开始的地址单元中存
放 30 个数据,找出其中的奇数存入内部 RAM 20H 开始的存储单元中,并统计奇数的个数,存入 3FH 单元。
用位操作指令对操作数最低位进行判断,若为 1 即为奇数。本题中, DPTR 是片外数据缓冲区地址指针,R0 是片内数据缓冲区地址指针。
第 4章 汇编语言程序设计
主讲 ; 吴政江
ORG 0030H
MOV DPTR , #1000H ;指向片外缓冲区首地址MOV R0 , #20H ;指向片内缓冲区首地址MOV R7 , #30H ;循环次数送入 R7
MOV 3FH , #00H ;清零LP: MOVX A , @DPTR ;取数JNB ACC.0 , EVEN ;偶数转 EVEN
MOV @R0 , A ;奇数保存INC R0 ;修改片内地址INC 3FH ;修改统计个数EVEN: INC DPTR ;修改片外地址DJNZ R7 , LP ;控制循环RET
第 4章 汇编语言程序设计
主讲 ; 吴政江
2 .排序 [ 例 4.20] 将片内 RAM 30H 开始的连续 16 个单元
的数据按从小到大的顺序排序。 此题采用的是冒泡排序法,即对这 16 个数据组成的
数据串,依次将相邻两数分别进行比较,若后面的数小于前面的数,则比较的相邻两数互换,且置位地址单元 7FH 为 1 。若这组数据比较完后,相邻两数有交换 ( 即交换标志位 7FH 为 1) ,则再重新进行两两比较,直到 16 个数已从小到大排序,相邻两数比较后不再交换为止。交换标志位 7FH 用来控制是否再需要重新两两比较。程序流程如图 4-7 所示。
第 4章 汇编语言程序设计
主讲 ; 吴政江
¿ª ʼ
Êý¾Ý¿éÊ×Ö·ËÍR1£¬ ¿é³¤1ËÍR7£¬½» »»±ê־λÇåÁã
È¡ÏàÁÚÁ½ÊýÖÐÇ°Ò»¸öÊýËÍ20Hµ¥Ôª
ÐÞ¸ÄÖ¸Õë
È¡ÏàÁÚÁ½ÊýÖкóÒ»¸öÊýËÍA
Ç°Êý£¼ºóÊý ?
Á½Êý½»»»
½»»»±ê־λÖÃλ
R7£ 1£½0 ?
½»»»±êÖ¾£½1 ?
½á Êø
N
Y
Y
N
N
Y
图 4-7 排序程序流程图
第 4章 汇编语言程序设计
主讲 ; 吴政江
程序如下:ORG 2000H
SORT : MOV R1 , #30H ;指向数据块首地址MOV R7 , #10H ;数据块长度送 R7
CLR 7FH ;交换标志位清零DEC R7 ;块长减 1 为比较次数
第 4章 汇编语言程序设计
主讲 ; 吴政江
LOOP1 : MOV A , @R1 ;取相邻两数中的前一个数MOV 20H , A
INC R1
MOV A , @R1;取相邻两数中的后一个数CJNE A , 20H , LOOP ;相邻两数比较LOOP: JNC NEXT ;前者小于后者转至 NEXT
XCH A , 20H ;前者大于后者,相邻两数互换MOV @R1 , A
第 4章 汇编语言程序设计
主讲 ; 吴政江
DEC R1
MOV @R1 , 20H
INC R1 ;恢复数据块指针SETB 7FH ;置 1 标志位NEXT: DJNZ R7 , LOOP1
;所有相邻两数未比较完,转至 LOOP1
JB 7FH , SORT ;交换标志位为 1 ,转至 SO
RT
RET
第 4章 汇编语言程序设计
主讲 ; 吴政江
4.4.4 算术运算 1 .多字节 BCD 码加法 [ 例 4.21] 已知在 BLOCK1 和 BLOCK2 为始址的存
储区中分别有长度为 N 字节压缩的 BCD 码,请编写程序使它们相加并将和送入 BLOCK1 为始址的存储单元。
使用加法指令从低字节相加,因为是 BCD 码相加,还需用 DA 指令调整。
第 4章 汇编语言程序设计
主讲 ; 吴政江
ORG 0100H
MOV R7 , #N ;数据块长度送 R7
MOV R0 , #BLOCK1 ;被加数始址送 R0
MOV R1 , #BLOCK2 ;加数始址送 R1
CLR C ; CY 清零LOOP : MOV A , @R0 ;被加数送 A
ADDC A , @R1 ;相加DA A ; BCD 码调整
第 4章 汇编语言程序设计
主讲 ; 吴政江
MOV @R0 。 A ;存和INC R0 ;修改被加数地址指针INC R1 ;修改加数地址指针DJNZ R7 , LOOP ;未加完,则转至 LOOP
JNC RTN ;最高位无进位转至 RTN
MOV @R0 , #01H ;有进位则保存RTN: RET
第 4章 汇编语言程序设计
主讲 ; 吴政江
2 .双字节无符号数乘法运算程序 [ 例 4.22] 已知在寄存器 R4R5 和 R2R3 中分别存放有
双字节的被乘数和乘数 (R5 、 R3 存放低 8 位, R4 、 R2
存放高 8 位 ) ,试编程求积并存入 BLOCK 开始的连续四个存储单元 ( 低字节在前,高字节在后 ) 。
AT89C51 乘法指令只能完成两个 8 位无符号数相乘,因此 16 位无符号数求积必须将它们分解成四个 8 位数相乘来实现,其方法是边乘边加。原理和过程如图 4-8 所示。
第 4章 汇编语言程序设计
主讲 ; 吴政江
a
c
b
d
R4
R2
R5
R3¡Á
bdH bdL
adLadH
bcLbcH
acLacH£«
»ý
Block£«3µ¥Ôª
Block£«2µ¥Ôª
Block£«1µ¥Ôª
Blockµ¥Ôª
图 4-8 双字节无符号数乘法原理图
第 4章 汇编语言程序设计
主讲 ; 吴政江
图中 ab 为 16 位被乘数, cd 为 16 位乘数 (a 、 c 代表高 8
位, b 、 d 代表低 8 位 ) ,而其后跟 H 表示乘积后的高 8 位,跟 L 表示乘积后的低 8 位。
ORG 1000H
BLOCK EQU 30H
MOV R0 , #BLOCK ;指向积单元首址MOV A , R5
MOV B , R3
MUL AB ; b×d
MOV @R0 , A ;保存 bdL
第 4章 汇编语言程序设计
主讲 ; 吴政江
MOV A , B
INC R0
MOV @R0 , A ;保存 bdH
MOV A , R4
MOV B , R3
MUL AB ; a×d
ADD A , @R0 ; bdH+adL
MOV @R0 , A
INC R0
MOV A , B
ADDC A , #00H ; adH+ 进位
第 4章 汇编语言程序设计
主讲 ; 吴政江
MOV @R0 , A
DEC R0
MOV A , R5
MOV B , R2
MUL AB ; b×c
ADD A , @R0 ; bcL 与 bdh 、 adL 、进位累加MOV @R0 , A
MOV A , B
第 4章 汇编语言程序设计
主讲 ; 吴政江
INC R0
ADDC A , @R0 ; bcH 与 adH 、进位累加MOV @R0 , A
INC R0
CLR A
ADDC A , #00H
MOV @R0 , A ;保存进位MOV A , R4
第 4章 汇编语言程序设计
主讲 ; 吴政江
MOV B , R2
MUL AB ; a×c
DEC R0
ADD A , @R0 ; acL 与 adH 、 bcH 、进位累加MOV @R0 , A
MOV A , B
INC R0
ADDC A , @R0 ; ac 与进位累加MOV @R0 , A
RET