当前位置:文档之家› 谈谈51单片机的指令字节数

谈谈51单片机的指令字节数

51单片机的指令字节数
现在的单片机程序大多都用C语言来编写了,汇编看起来有点OUT了。可是有时候汇编却很有用,因为
MCS-51单片机的指令的字节数。
汇编语言的语句的格式为:
标号段: 操作码段 第一操作数,第二操作数 ;注释段 (如
: MOV A,#00H ;把0赋给A)
其中操作码段是必段的,其他的段是根据不同的指令而不同,操作数段可以只有一个操作数,

在51单片机中,有单字节指令、双字节指令和三字节指令。只要理解了指令占用的这些字节

1、操作码段占用一个字节。
2、8位立即数占用一个字节,16位立即数占用两个字节。
3、8位操作数地址占用一个字节,16位操作数地址占用两个字节。
4、CPU内部的各种寄存器不占用指令字节,如A, B, R0, R1, DPTR等。
现在就可以判断51的指令占用的字节数了:
MOV A, R0 ; 这是单字节指令,其中MOV占用一个字节,A和R0是CPU内

MOV A, #07H ;这是双字节指令,其中MOV占用一个字节,8位立即数#07H占用

MOV DPTR, #0106H ;这是三字节指令, MOV占用一个字节,16位立即数#0106H

MOV 07H, #07H ;这是三字节指令,MOV占用一个字节,8位地址07H占用一个
8位立即数#07H占用一个字节。
BCD 码减数求补的问题


ORG 0100H
MOV R1, #50H
MOV R0, #60H
CLR C
CALL BSUB
MOV 40H, A
.
.
.
A, #9AH
SUBB A, @R0
ADD A, @R1
DA A
INC R0
INC R1
CPL C
RET
9AH 的作用是什么,能不能换成别的数!
BCD 码减法程序。

回答: | 五级 2009-8-29 09:58
MCS-51 单片机的汇编语言,很多人都不懂的。
(50H)-(60H)-->(40H) 的 BCD 码减法运算;并且对源数据的地址指针进行了修正。
码的运算之后,应(使用 DA A指令)进行十进制调整,将运算结果修正为 BCD 码;
MCS-51 单片机的 DA A 指令只能放在加法之后,它对减法不起作用。
BCD 码的减法必须变换成加法,才能用 DA A 指令进行十进制调整。
15分,和正拨45分,效果相同的方法,可将:
(50H) - (60H)

(50H) + [100 - (60H)]
100,又等效写成 9AH,不信,你对它 DA A 试试,马上就是 100H,这就是 100 的 BCD码,



“减数求补”的问题,是 MCS-51 单片机的汇编语言中,特有的问题。
BCD 码相减,如果想要得到 BCD 码形式的结果,就应该进行十进制调整。
MCS-51 单片机的十进制调整指令 (DA A) 只能放在加法指令之后,它对减法不起作用。
BCD 码的减法,必须变换成加法

进行,才能使用 DA A 指令进行十进制调整。
“补数”的问题。
15 分和正拨 45 分,效果是相同的。
60-15=45 求出 15 对 60 的补数 45。
2 位十进制数字的补数,要用如下公式进行计算:
99+1 - (减数) = 补数 (BCD码最大值为99,加1以后就溢出,在计算机溢出以后又回0,有个模的
9AH=99+1,正好是100,加个溢出值不影响本数,所以就为9A-减数,这和2进制的概念一样,2进
FF-减数+1,而FF-减数就是取反,所以求补是取反加1,明白码?)
“和”就是原来要求出的“差”了。
DA A 指令进行调整了。
100,可等效写成 9AH,当对它进行 DA A 调整后,它就会变成 100H。
和 100H,都是 100 的 BCD 码。
“补数”和求“补码”都是相同的。
87 - 34 = 53

9AH -34H = 66H
87H + 66H = EDH
DA A后得:153H
把进位 1 丢弃,结果就是 53 的 BCD 码 53H。
DA A也会改变PSW中的进位标志位!
示例:如果累加器中的内容为56H(01010110B),表示十进制数56的BCD
3的内容为67H(01100111B),表示十进制数67的BCD码。进位标志
1,则指令
ADDC A,R3
DA A
先执行标准的补码二进制加法,累加器A的值变为0BEH,进位标志和
接着,DA执行十进制调整,将累加器A的内容变为24H(00100100B),
24的BCD码,也就是56、67及进位标志之和的后两位数字。DA
1,这表示在进行十进制加法时,发生了溢出。56、67以及1
124。
!!呵呵!!也就是说,一旦有中断,硬件会
而跳往中断入口地址,在中断入口地址处有 中断处理函数 ;等

,人家厂商做的,没办法,,更可恨的是,把中断入口地址从0003H 开
,每隔7 个单元 放一个 中断入口;;;依次是:
000BH——0013H——001B——0023H
,是你配置的(INT0,INT1,T0,T1,串口)中断类型;
硬件 自动跳到,不归你管啊!!!要是隔着的那七个地址单
写中断处理函数怎么办呢???那就先跳转到另一个空地上,等做好事情后再 调回
,之后 再跳回到 程序停止的 地方!!!呵呵!!!!!不知明白了没?????关于
我的空间,,谢谢!!!


;串行通信是指数据一位位地顺序传送.奇偶校验是
,在需要传输的信息位以外添加一位校验位,奇校验是设
"1"或"0"使整个单元"1"的个数为奇数,偶校验则使"1"的个数为偶数. 当接受端发
.这种校验方法用于
1位误码,如果错误码多于一位就失去了检错的作用.表示信号传输实
,即单位时间内传输的二进制码的有效位数(如bit/s).而波特率是指
,载波调制信号用载波的不同调制状态来表示二进制的信号,如单相调
,分别表示"0"和"1", 四相调制有4

个状态 表示二位二进制数"00", "01", "10"和
,八相调制有3位,以此类推. 因此,单相调制的波特率和比特率相等,四相调制的
2倍,八相是3倍.....kpt希望采纳我的

.1 利用dac0832产生三角波
序介绍:单片机通过DAC0832转换在LM358的7脚输
三角波。实际应用如:函数波形发生器。
序实例(0832shan.asm):
选通地址
通过上升和下降来产生三角波///////////////////
电压随时间上升///////////////////////////////
电压随时间下降///////////////////////////////
利用dac0832产生方波
序介绍:程序介绍:单片机通过DAC0832转换在
的7脚输出方波。实际应用如:函数波形发生器。
序实例(0832fan.asm):
通过高低电平地的变化来输出方波///////////
向选通地址送低电平地
向选通地址送高电平
延时,通过改变它的大小
以改变占空比
利用dac0832产生正弦波
序介绍:程序介绍:单片机通过DAC0832转换在
的7脚输出正弦波。实际应用如:函数波形发生器。
序实例(0832xuan.asm):
取表格初值
在表格里取数送到指定地址/////////////////////
表格加一
循环
正弦表格/////////////////////////////////////
38H
利用dac0832产生梯形波
序介绍:程序介绍:单片机通过DAC0832转换在
的7脚输出梯形波。实际应用如:函数波形发生器。
序实例(0832ti.asm):
选通地址
延时
每次以19H的梯度增加
梯度等待的时间
循环
单片机在执行短调用指令(ACALL)时,在调用操作之前为什么PC要先加2?
PC。
PC
Program Counter),是程序计数器,是一个16位的专用寄存器,用来存放下一条指
。当CPU 要
PC的内容首先送至地址总线上,然后再从存储器中取出指令,取指令后,PC
1,指向下一条指令的地址(这句话很关键)。
ACALL
它本身占2个字节的存储单元。为了保证子程序返回后程序按
PC内容要先加2,指向ACALL指令后的单元,以便顺序执行。
谈谈51单片机延时子程序
但一些读者在学习中不知道延时程序怎么编程,



那么执行一个机器周期就只需要1μs;如果采用的是6MHz的晶
μs。

(执行这条指令只需一个机器周期),双周期指令(执行这
,四周期指令(执行这条指令需要四个机器周期)。除了乘、除




MOV

R7,#80H;将数据80H送到寄存器R7,这时寄存器R7里面存

NOP

DJNZ

R7,KK ;将寄存器R7的内容减1并判断寄存器R7里的内容减
则转移到地址标号为KK的地方;如果为0则执行下一条指


μs)

程序总共所需时间:1+10+2560+330240+660480+5120+20+2=

998433μs≈1s
μs,还差1567μs才达到1s的,所以想要
s延时,需要在返回指令RET前再添加一些指令让它把1567μs的延时完



R7,$ ;R7内容减1不为0,则再次执行本指令;为0则往下执行,
μs。
51单片机汇编延时程序算法详解


CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,



×(1/12000000)=1μs。
程序分析
50ms延时子程序:
DEL:MOV R7,#200 ①
DEL1:MOV R6,#125 ②
DEL2:DJNZ R6,DEL2 ③
DJNZ R7,DEL1 ④
RET ⑤
1+(1*200)+(2*125*200)+(2*200)+2
=(2*125+3)*200+3 ⑥
=50603μs≈50ms


R7,#200 在整个子程序中只被执行一次,且为单周期指令,
μs
MOV R6,#125 从②看到④只要R7-1不为0,就会返回到这句,
μs
R6,DEL2 只要R6-1不为0,就反复执行此句(内循环
,又受外循环R7控制,所以共执行R6*R7次,因是双周期指令,所以耗时2*
μs。
1秒延时子程序:
DEL:MOV R7,#10 ①
DEL1:MOV R6,#200 ②
DEL2:MOV R5,#248 ③
DJNZ R5,$ ④
DJNZ R6,DEL2 ⑤
DJNZ R7,DEL1 ⑥
RET ⑦
对每条指令进行计算得出精确延时时间为:
=[(2*248+3)*200+3]*10+3 ⑧
=998033μs≈1s

(2*第一层循环+3)*第二层循环+3]*第三层循环+3⑨


例3仍以1秒延时为例
DEL:MOV R7,#10 1指令周期1
DEL1:MOV R6,#0FFH 1指令周期10
DEL2:MOV R5,#80H 1指令周期255*10=2550
KONG:NOP 1指令周期128*255*10=326400
DJNZ R5,KONG 2指令周期2*128*255*10=652800
DJNZ R6,DEL2 2指令周期2*255*10=5110
DJNZ R7,DEL1 2指令周期2*10=20
RET 2
=1+10+2550+326400+652800+5110+20+2 =986893μs约为1s
:延时时间=[(3*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑩

延时为:20ms 晶振12M
..优点就是精确...缺点就是算有点复杂.
DJNZ R6,$
DJNZ R7,D1
NOP
NOP
RET
延时子程序(12MHz晶振):
MOV R7,#200 ;单周期指令(1us)
;单周期指令(1us)
DJNZ R6,$ ;双周期指令(2us)//该指令自身执行R6次
DJNZ R7,D1 ;双周期指令(2us)//D1执行R7次
RET ;双周期指令(2us)
=100603us ≈0.1s
延时子程序(12MHz晶振):
MOV R7,#5 ;单周期指令(1us)
MOV R6,#200 ;单周期指令(1us)
MOV R5,#250 ;单周期指令(1us
DJNZ R5,$ ;双周期指令(2us)//该指令自身执行R5次
DJNZ R6,D2

;双周期指令(2us)//D2执行R6次
DJNZ R7,D1 ;双周期指令(2us)//D1执行R7次
RET ;双周期指令(2us)
=503018us ≈0.5s
我查了ORG是为了给
ORG 0000H定位程序从0000H开始存放,之后就跳转到
程序了啊,那后面一条ORG 0030H定位语句有什么作用
是个用于定位的伪指令。简单的说就是把从这句话开始直到下一个ORG指令或者
指令前的程序语句都顺序放在它指定的地址里。比如说你的程序里ORG只管了一个语
(AJMP MAIN),则从0000h这个地址开始放语句。放多少,看下面有几条语句(直到org
end 指令为止)。同样ORG 0030H是把它后面的所有到下一个ORG或END命令前的
0030H开始的程序单元。这应该是一个子程序。就像C语言里的子


相关主题
文本预览
相关文档 最新文档