单片机中伪指令 求教

2024-12-01 05:17:34
推荐回答(2个)
回答1:

你提的问题是一个很多学生甚至教单片机的老师都不理解的一个问题。我们大学学单片机只是了解但是没有真正的把硬件和软件与实际联系到一起。不过为了深入了解我也细细的说一些单片机的工作机制,这样学起来也比较简单(呵呵,本人编程编的实在太累了,就当休息),在这里可能我讲了一些要慢慢了解。
在了解之前要说几个概念、单片机工程文件、烧录文件、程序存储区、运算单元、RAM
先从硬件开始说,因为工程文件、烧录文件是后来发展形成的。这要从计算机历史讲起。最初的计算机是没有程序存储器的,采用布线接板进行控制,后来改用带孔的纸板插入计算机光电管和灯泡之间来表示数据和程序,控制程序流程的走向。这是程序存储器的最初雏形,传动装置将纸板传入光电管和灯泡之间,计算机开始计算或控制程序走向。比如10cm的纸板有3个孔表示程序结束,10cm的纸板有2个孔表示数据相加,那么传动到哪里就执行哪里的程序。遇到10cm的纸板有3个孔计算机就停止。
最初是10进制。后来因为二进制对于计算机好识别才有了二进制。也增添了程序存储器,程序存储器就是用来控制程序走向和数据计算的依据单元。
了解硬件发展以后我们看一段程序,程序很简单。计算4+5=9,呵呵幼儿班数学,可是单片机是如何算出来的呢,我们看个究竟。设RAM中R0的数据为4,R1里的数据为5,结果存到R2中,循环计算。 程序如下(一会通过加入其它伪指令来讲述)
ORG 0000H
LJMP Start
ORG 0006H
Start: MOV R0,#04H
MOV R1,#05H
Main: MOV A,R0
ADD A,R1
MOV R2,A
LJMP Start
END
其中ORG为伪指令END也为伪指令。
有了这些程序单片机是如何工作的呢,我们能看懂程序但是单片机并不认识程序,它只能识别0和1组成的数据,为了不像最初的控制计算机流程一样布线接板或者插纸板单片机中增加了很多东西如程序指针SP和程序存储器。
我们编写完程序后建立工程文件然后编译成烧录文件烧录到单片机里(后面再讲编译)。
我们看看程序存储区是什么个样子。
地址 数据
0x0000 02H
0x0001 00
0x0002 06
0x0003 00
0x0004 00
0x0005 00
0x0006 78
0x0007 04
0x0008 79
0x0009 05
0x000A E8
0x000B 29
0x000C FA
0x000D 02
0x000E 00
0x000F 06
我们看到只是一些数据而已,单片机是如何执行的呢。下面我们分析一下。
单片机指令是由操作码、操作数组成,操作码是表明指针所指指令作用的标志数据,操作数则是要执行任务的数据依据,如LJMP Start 操作码、操作数分别为02H和Start。在上电后SP指针的值指向0x0000位置。遇到的第一个指令是SJMP Start由于Start是人为为地址起的名字因此不会被存入单片机存储器中,而是找到地址计算其跳转地址(名称相同就求出地址了),这个程序计算结果是0x0006,这样LJMP Start 的指令字节数为3个。
地址 数据
SP->0x0000 02H
0x0001 00
0x0002 06
0x0003 00
0x0004 00
0x0005 00
0x0006 78
0x0007 04
0x0008 79
0x0009 05
0x000A E8
0x000B 29
0x000C FA
0x000D 02
0x000E 00
0x000F 06
我将程序存储区数据和数据表联系起。
地址 数据
0x0000 02H ORG 0000H
LJMP Start
0x0001 00
SP->0x0002 06
0x0003 00
0x0004 00
0x0005 00
0x0006 78 ORG 0006H
Start: MOV R0,#04H
0x0007 04
0x0008 79 MOV R1,#05H
0x0009 05
0x000A E8 Main: MOV A,R0
0x000B 29 ADD A,R1
0x000C FA MOV R2,A
0x000D 02 LJMP Start
0x000E 00
0x000F 06
END
ORG表示下一行指令从哪一个地址开始写,END表示程序结束,如果我们在加入一个伪指令EQU 编译后会出现什么结果。
First EQU R0
Second EQU R1
Result EQU R2
ORG 0000H
LJMP Start
ORG 0006H
Start: MOV First,#04H
MOV Second,#05H
Main: MOV A,First
ADD A,Second
MOV Result,A
LJMP Start
END
地址 数据
First EQU R0
Second EQU R1
Result EQU R2
0x0000 02H ORG 0000H LJMP Start
0x0001 00
SP->0x0002 06
0x0003 00
0x0004 00
0x0005 00
0x0006 78 ORG 0006H
Start: MOV First,#04H
0x0007 04
0x0008 79 MOV Second,#05H
0x0009 05
0x000A E8 Main: MOV A,First
0x000B 29 ADD A,Second
0x000C FA MOV Result,A
0x000D 02 LJMP Start
0x000E 00
0x000F 06
END

我们会发现编译后的结果是一样的,这些伪指令虽然作用不同但是有一个共同特点就是在程序存储器中不产生可执行的操作码和操作数,只是为了编程人方便或注释或可以影响数据存储位置的指令称为伪指令。
First EQU R0
Second EQU R1
Result EQU R2
ORG 0000H
LJMP Start
ORG 0006H
Start: MOV First,#04H
MOV Second,#05H
Main: MOV A,First
ADD A,Second
MOV Result,A
LJMP Start
DW 30H,60H,90H
END
编译结果如下,从10H开始。因此DW30H是0030
0x0000 02H
0x0001 00
SP->0x0002 06
0x0003 00
0x0004 00
0x0005 00
0x0006 78
0x0007 04
0x0008 79
0x0009 05
0x000A E8
0x000B 29
0x000C FA
0x000D 02
0x000E 00
0x000F 06
0x0010 00
0x0011 30
0x0012 00
0x0013 60
0x0014 00
0x0015 90
晕,百度知道复制超过太多字节的数据复制不上

回答2:

是这样的,DW 30H,存放的是00H 30H,伪指令是为了方便阅读和修改程序