标题: 8课:单片机寻址方式与指令系统 [打印本页]

作者: admin    时间: 2013-5-21 03:04
标题: 8课:单片机寻址方式与指令系统
  通过前面的学习,我们已经了解了单片机内部的结构,并且也已经知道,要控制单片机,让它为我们干学,要用指令,我们已学了几条指令,但很零散,从现在开始,我们将要系统地学习8051单片机的指令部份。一、概述
1、指令的格式
   我们已知,要让计算机做事,就得给计算机以指令,并且我们已知,计算机很“笨”,只能懂得数字,如前面我们写进机器的75H,90H,00H等等,所以指令的第一种格式就是机器码格式,也说是数字的形式。但这种形式实在是为难我们人了,太难记了,于是有另一种格式,助记符格式,如MOV P1,#0FFH,这样就好记了。 这两种格式之间的关系呢,我们不难理解,本质上它们完全等价,只是形式不一样而已。
2、汇编
  我们写指令使用汇编格式,而计算机和单片机只懂机器码格式,所以要将我们写的汇编格式的指令转换为机器码格式,这种转换有两种办法:手工汇编和机器汇编。手工汇编实际上就是查表,因为这两种格式纯粹是格式不一样,所以是一一对应的,查一张表格就行了。不过手工查表总是嫌麻烦,所以就有了计算机软件,用计算机软件来替代手工查表,这就是机器汇编。
二、单片机的寻址
  让我们先来复习一下我们学过的一些指令:MOV P1,#0FFH,MOV R7,#0FFH这些指令都是将一些数据送到对应的位置中去,为什么要送数据呢?第一个因为送入的数能让灯全灭掉,第二个是为了要实现延时,从这里我们能看出来,在用单片机的编程语言编程时,经常要用到数据的传递,事实上数据传递是单片机编程时的一项重要工作,一共有28条指令(单片机共111条指令)。下面我们就从数据传递类指令开始吧。
  分析一下MOV P1,#0FFH这条指令,我们不难得出结论,第一个词MOV是命令动词,也就是决定做什么事情的,MOV是MOVE少写了一个E,所以就是“传递”,这就是指令,规定做什么事情,后面还有一些参数,分析一下,数据传递必须要有一个“源”也就是你要送什么数,必须要有一个“目的”,也就是你这个数要送到什么地方去,显然在上面那条单片机指令中,要送的数(源)就是0FFH,而要送达的地方(目的地)就是P1这个寄存器。在数据传递类指令中,均将目的地写在指令的后面,而将源写在最后。
  这条指令中,送给P1是这个数本身,换言之,做完这条指令后,我们能明确地知道,P1中的值是0FFH,但是并不是任何时候都能直接给出数本身的。例如,在我们前面给出的单片机延时程序例是这样写的:
MAIN: SETB P1.0     ;(1)
   LCALL DELAY ;(2)
    CLR P1.0      ;(3)
   LCALL DELAY   ;(4)
    AJMP MAIN    ;(5)
;以下子程序
DELAY: MOV R7,#250   ;(6)
D1: MOV R6,#250   ;(7)
D2: DJNZ R6,D2    ;(8)
   DJNZ R7,D1   ;(9)
   RET        ;(10)
   END        ;(11)
表1
-----------------------------------------------------
MAIN: SETB P1.0     ;(1)
   MOV 30H,#255
    LCALL DELAY ;
    CLR P1.0      ;(3)
    MOV 30H,#200
    LCALL DELAY   ;(4)
    AJMP MAIN    ;(5)
;以下子程序
DELAY: MOV R7,30H   ;(6)
D1: MOV R6,#250   ;(7)
D2: DJNZ R6,D2    ;(8)
   DJNZ R7,D1   ;(9)
   RET        ;(10)
   END        ;(11)
表2
 这样一来,我每次调用延时程序延时的时间都是相同的(大致都是0.13S),如果我提出这样的要求:灯亮后延时时间为0.13S灯灭,灯灭后延时0.1秒灯亮,如此循环,这样的程序还能满足要求吗?不能,怎么办?我们能把延时程序改成这样(见表2):调用则见表2中的主程,也就是先把一个数送入30H,在子程序中R7中的值并不固定,而是根据30H单元中传过来的数确定。这样就能满足要求。

   从这里我们能得出结论,在数据传递中要找到被传递的数,很多时候,这个数并不能直接给出,需要变化,这就引出了一个概念:如何寻找操作数,我们把寻找操作数所在单元的地址称之为寻址。在这里我们直接使用数所在单元的地址找到了操作数,所以称这种办法为直接寻址。除了这种办法之外,还有一种,如果我们把数放在工作寄存器中,从工作寄存器中寻找数据,则称之为寄存器寻址。例:MOV A,R0就是将R0工作寄存器中的数据送到累加器A中去。提一个问题:我们知道,工作寄存器就是内存单元的一部份,如果我们选择工作寄存器组0,则R0就是RAM的00H单元,那么这样一来,MOV A,00H,和MOV A,R0不就没什么区别了吗?为什么要加以区别呢?的确,这两条指令执行的结果是完全相同的,都是将00H单元中的内容送到A中去,但是执行的过程不一样,执行第一条指令需要2个周期,而第二条则只需要1个周期,第一条指令变成最终的目标码要两个字节(E5H 00H),而第二条则只要一个字节(E8h)就能了。

  这么斤斤计较!不就差了一个周期吗,如果是12M的晶体震荡器的话,也就1个微秒时间了,一个字节又能有多少?
   不对,如果这条指令只执行一次,也许无所谓,但一条指令如果执行上1000次,就是1毫秒,如果要执行1000000万次,就是1S的误差,这就很可观了,单片机做的是实时控制的事,所以必须如此“斤斤计较”。字节数同样如此。
再来提一个问题,现在我们已知,寻找操作数能通过直接给的方式(立即寻址)和直接给出数所在单元地址的方式(直接寻址),这就够了吗?
看这个问题,要求从30H单元开始,取20个数,分别送入A累加器。
   就我们目前掌握的办法而言,要从30H单元取数,就用MOV A,30H,那么下一个数呢?是31H单元的,怎么取呢?还是只能用MOV A,31H,那么20个数,不是得20条指令才能写完吗?这里只有20个数,如果要送200个或2000个数,那岂不要写上200条或2000条命令?这未免太笨了吧。为什么会出现这样的状况?是因为我们只会把地址写在指令中,所以就没办法了,如果我们不是把地址直接写在指令中,而是把地址放在另外一个寄存器单元中,根据这个寄存器单元中的数值决定该到哪个单元中取数据,比如,当前这个寄存器中的值是30H,那么就到30H单元中去取,如果是31H就到31H单元中去取,就能解决这个问题了。怎么个解决法呢?既然是看的寄存器中的值,那么我们就能通过一定的办法让这里面的值发生变化,比如取完一个数后,将这个寄存器单元中的值加1,还是执行同一条指令,可是取数的对象却不一样了,不是吗。通过例程来说明吧。
MOV R7,#20
   MOV R0,#30H
LOOP:MOV A,@R0
   INC R0
   DJNZ R7,LOOP
    这个例程中大部份指令我们是能看懂的,第一句,是将立即数20送到R7中,执行完后R7中的值应当是20。第二句是将立即数30H送入R0工作寄存器中,所以执行完后,R0单元中的值是30H,第三句,这是看一下R0单元中是什么值,把这个值作为地址,取这个地址单元的内容送入A中,此时,执行这条指令的结果就相当于MOV A,30H。第四句,没学过,就是把R0中的值加1,因此执行完后,R0中的值就是31H,第五句,学过,将R7中的值减1,看是否等于0,不等于0,则转到标号LOOP处继续执行,因此,执行完这句后,将转去执行MOV A,@R0这句话,此时相当于执行了MOV A,31H(因为此时的R0中的值已是31H了),如此,直到R7中的值逐次相减等于0,也就是循环20次为止,就实现了我们的要求:从30H单元开始将20个数据送入A中。
这也是一种寻找数据的办法,由于数据是间接地被找到的,所以就称之为间址寻址。注意,在间址寻址中,只能用R0或R1存放等寻找的数据。


作者: 812125810    时间: 2013-5-23 23:04
很好!
作者: 阿格拉瑞    时间: 2013-5-25 22:00
顶一顶
作者: 不加糖的咖啡    时间: 2013-8-1 17:19
非常不错
作者: danpianji889    时间: 2013-8-13 15:14
我还是理解不是很多的
作者: humerss    时间: 2013-9-4 16:15
要去实践才好啊
作者: humerss    时间: 2013-9-4 16:15

作者: wuspace    时间: 2013-9-12 15:47
不错。学习中
作者: xiafei    时间: 2013-12-7 15:31
不错 值得学习
作者: 追风逐月    时间: 2013-12-16 14:49
很好,易懂
作者: 隆威    时间: 2014-2-7 20:12
谢谢了 看了有难度 不过还是有信心
作者: 隆威    时间: 2014-2-8 15:46
楼主辛苦了
作者: 呜呜呜呜    时间: 2014-3-5 12:48
如何理解主程序,子程序?不用子程序还能执行程序不?
作者: 呜呜呜呜    时间: 2014-3-6 21:53
这里怎么不用返回程序呀
作者: jiajun678    时间: 2014-4-4 22:00
受益匪浅。
作者: lixichunedu    时间: 2014-4-5 15:52
受益匪浅,解释得很清晰。机器的工作也是按照我们人类的思维去创造的。 讲得很好。
作者: 雪中梅花    时间: 2014-5-19 13:37
楼主辛苦了。
作者: 雨中的角落    时间: 2014-6-22 11:16
想买个单片机使用试试看
作者: 霸道小皇帝    时间: 2014-7-15 11:32
讲解的很棒
作者: 神一般的存在    时间: 2014-7-16 14:51
通熟易懂
作者: 亭子    时间: 2014-7-24 17:23
有点眉目啦
作者: SHANGYU    时间: 2014-9-9 09:11
很好的教材!
作者: yingtn    时间: 2014-9-11 17:37
匯編語言程序多,是否可有C語言學習呢?
作者: 白菜94    时间: 2014-10-26 12:22
nice nice
作者: 巡航12    时间: 2014-11-18 16:54
写的真好,好多书是写给懂了的人看的,没懂的再看也不懂,这里不懂的人也能看懂,出书吧,盼着
作者: xiejian5164    时间: 2014-11-30 11:39
deng  xuexi
作者: ardu    时间: 2014-12-18 20:03
初学者  
作者: wwtian    时间: 2014-12-19 09:36
谢谢老师,讲得真好,相当容易接受!谢谢您无偿又耐心奉献!
作者: 徘徊快乐    时间: 2014-12-19 21:39
很好。
作者: 山一样的男人    时间: 2015-1-4 11:05
8课比7课好了解的多了 继续
作者: O_o_Hong    时间: 2015-2-5 20:19
不错的教程呢,比较精华,谢了
作者: 挪亚易    时间: 2015-2-21 11:33
确实讲的比教材易懂
作者: zzqzhang    时间: 2015-2-24 15:31
谢谢分享,好好学习。
作者: dimozun    时间: 2015-3-31 15:25
基本明白了,不错!!!
作者: b4082    时间: 2015-4-6 10:56
感谢分享,谢谢!
作者: 崔三爷    时间: 2015-4-18 17:45
给力给力给雷、黎
作者: cikesheshou    时间: 2015-4-29 23:53
开始难了
作者: 201330030167    时间: 2015-4-30 18:45
很给力
作者: hzy    时间: 2015-5-8 18:07
真好啊,有电子版的吗?
作者: 疯子945    时间: 2015-5-26 22:35
主好強大,頂!
作者: zhghan62    时间: 2015-8-18 23:16
讲的很生动,是普及单片机的好教材‘
作者: hzb123    时间: 2015-8-23 07:59
易懂,很不错
作者: pandslu    时间: 2015-8-23 23:20
路过看看  很好
作者: 1qaz2wsx77    时间: 2015-10-25 20:54
通俗易懂。找这些资料也不容易呀

作者: satan    时间: 2016-1-4 23:47
很好 ,好好学习
作者: 嗯哼    时间: 2016-2-1 10:20
下一刻的链接咋没啦
作者: cloudflyxia    时间: 2016-3-22 21:30
上大学学的汇编,早还给老师了
作者: 阿小哥    时间: 2016-4-9 23:26
你的照片挡我手机上的字了,能移开吗?
作者: 阿小哥    时间: 2016-4-9 23:33
你的照片挡住我手机上的字了,能移开吗?
作者: 阿小哥    时间: 2016-4-10 00:12
好懂!我只有一本单片机的书,看了好久也不懂多少。看了你的文章就懂多了!谢谢!!!!!!
作者: lgs    时间: 2016-4-20 20:14
希望加入操作数等术语的定义,虽然可以自行百度。
作者: kkkklkl    时间: 2016-5-24 11:26
从此,讨好I人/九O星\\i/
作者: zwk34    时间: 2016-8-12 21:49
很好,讲的很细致。
作者: WWWJJJGGG    时间: 2016-9-12 23:18
很好,但有些看得不是很懂。
作者: B型血    时间: 2016-11-9 20:08
这一节好理解
作者: 51爱飞    时间: 2017-2-5 15:26
顶一个,很好
作者: AD-Asiens    时间: 2017-2-9 14:31
冒昧的问下,单片机入门必须要学习汇编和指令系统吗,有么有直接C语言用来编程的教学资料啊?
作者: zhhl008    时间: 2017-2-9 23:22
看不太懂
作者: 新月传说    时间: 2017-2-15 17:02
后面的例题是将30H至后面的20个数累加到A去吗?没学过,刚看看
作者: AD-Asiens    时间: 2017-2-22 16:00
要是能把C51也对照写出来就好了。
作者: zrx15756000859    时间: 2017-3-9 13:13
不错,爱看书更容易让人理解
作者: tramp··    时间: 2017-4-6 21:30
不错。。。。
作者: yonghu    时间: 2017-5-27 18:24
看到是汇编语言就不想看了
作者: lianglj0    时间: 2017-6-16 16:47
大赞,非常好的入门教程
作者: lianglj0    时间: 2017-6-16 16:48
还有吗?怎么看不到了
作者: MEIXIUQUAN    时间: 2017-8-15 06:06
不错,非常好,讲的很明白
作者: jiangmin    时间: 2017-9-22 01:15
讲的很细致。
作者: hsyxyz123    时间: 2017-11-23 15:38
看来这个寻址方式和ARM的寻址方式很象呀。
作者: wy_168    时间: 2017-11-23 20:51
很好。
作者: 150230117    时间: 2017-12-20 18:22
很好,值得学习
作者: liuzclzc    时间: 2018-1-16 20:29
这节学的指令的汇编格式
作者: BXG    时间: 2018-1-18 15:29
非常不错
作者: wc905705586    时间: 2018-1-24 09:02
那A中的值是不是一直被覆盖吗?这个主要是用A做什么用呢。不理解。
作者: wuzjh    时间: 2018-1-31 16:53
请教admin老师:寄存器或单元里的数据被读取或被送出后,该单元或寄存器中原先的数据是否还存在或保留呢?谢谢了!
作者: wuzjh    时间: 2018-1-31 19:28
wuzjh 发表于 2018-1-31 16:53
请教admin老师:寄存器或单元里的数据被读取或被送出后,该单元或寄存器中原先的数据是否还存在或保留呢? ...

同时请教行内其他专家,还有谁能赐教上述问题。谢谢了!
作者: chldxj912    时间: 2018-3-21 15:48
不错。学习学习
作者: MrCcccc    时间: 2018-3-25 23:00
点赞!!谢谢分享!
作者: ghdok    时间: 2018-4-1 18:27
学习中
作者: ghdok    时间: 2018-4-1 18:28
谢谢 学习
作者: exkrqo    时间: 2018-4-18 13:07
说的非常清楚明白,给力
作者: 57185490    时间: 2018-5-2 18:27
这一篇比较容易看懂
最好就是这样 给个程序
再逐条分析
作者: niuniniu    时间: 2018-6-18 16:22
这个是汇编吧 不是c语言吧
作者: niuniniu    时间: 2018-6-18 16:23
不像是c语言
作者: keneng    时间: 2018-6-25 16:28
继续学习,认真学习。
作者: jxhjjm    时间: 2018-6-28 11:08

非常不错
作者: 陶陶高中    时间: 2018-7-13 10:00
不错啊
作者: yaojc1    时间: 2018-7-26 09:07
谢谢分享!
作者: songyuan    时间: 2018-7-26 11:04
受益匪浅,解释得很清晰。机器的工作也是按照我们人类的思维去创造的。 讲得很好。
作者: zhoujd    时间: 2018-8-2 07:05
这个要慢慢看,慢慢理解
作者: Tom-Cao    时间: 2018-9-8 08:58
复杂问题简单化,讲解的通俗易懂!赞
作者: Miaoanjun    时间: 2018-9-9 16:52
很好好理解多啦
作者: 暗黑暗夜    时间: 2018-9-30 07:30
真的很不错
作者: qq1879316784    时间: 2018-10-11 21:14
解释的好
作者: hlfqzy    时间: 2018-10-13 08:07
非常不错
作者: YSG6649    时间: 2019-3-20 15:05
        赞一个!
作者: 只有五毛的忧伤    时间: 2019-3-26 20:32
设计cpu的时候是根据指令系统来设计的,可是我们在用单片机的时候不是把汇编程序编译成hex文件再存到ram里面么,那这样的话还怎么根据51的汇编指令设计单片机相应的cpu core呢
作者: 大地的    时间: 2020-1-21 23:11
霸道小皇帝 发表于 2014-7-15 11:32
**** 作者被禁止或删除 内容自动屏蔽 ****

讲的很好
作者: 老顽童63    时间: 2020-8-22 01:19
我一口气从开始学习到这里,很感谢你,通俗易懂
作者: cedtek    时间: 2020-12-29 16:29
寄存器寻址和从缓存中取数据有些相同点,效率相比直接从ROM中取数据都有提高,设计这些电路的前辈们太伟大了
作者: 孤独的狂欢    时间: 2021-6-20 22:30
这是不是就是算法逻辑




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1