指令

单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。计算机每执行一条指令都可分为三个阶段进行。即取指令-----分析指令-----执行指令

取指令的任务是:根据程序计数器PC中的值从程序存储器读出现行指令,送到指令寄存器。

分析指令阶段的任务是:将指令寄存器中的指令操作码取出后进行译码,分析其指令性质。如指令要求操作数,则寻找操作数地址。

计算机执行程序的过程实际上就是逐条指令地重复上述操作过程,直至遇到停机指令可循环等待指令。

一般计算机进行工作时,首先要通过外部设备把程序和数据通过输入接口电路和数据总线送入到存储器,然后逐条取出执行。但单片机中的程序一般事先我们都已通过写入器固化在片内或片外程序存储器中。因而一开机即可执行指令。

下面我们将举个实例来说明指令的执行过程:

开机时,程序计算器PC变为0000H。然后单片机在时序电路作用下自动进入执行程序过程。执行过程实际上就是取出指令(取出存储器中事先存放的指令阶段)和执行指令(分析和执行指令)的循环过程。

例如执行指令:MOV A,#0E0H,其机器码为“74H E0H”,该指令的功能是把操作数E0H送入累加器,0000H单元中已存放74H,0001H单元中已存放E0H。当单片机开始运行时,首先是进入取指阶段,其次序是:

① 程序计数器的内容(这时是0000H)送到地址寄存器;

② 程序计数器的内容自动加1(变为0001H);

③ 地址寄存器的内容(0000H)通过内部地址总线送到存储器,以存储器中地址译码电跟,使地址为0000H的单元被选中;

④ CPU使读控制线有效;

⑤ 在读命令控制下被选中存储器单元的内容(此时应为74H)送到内部数据总线上,因为是取指阶段,所以该内容通过数据总线被送到指令寄存器。

至此,取指阶段完成,进入译码分析和执行指令阶段。

由于本次进入指令寄存器中的内容是74H(操作码),以译码器译码后单片机就会知道该指令是要将一个数送到A累加器,而该数是在这个代码的下一个存储单元。所以,执行该指令还必须把数据(E0H)从存储器中取出送到CPU,即还要在存储器中取第二个字节。其过程与取指阶段很相似,只是此时PC已为0001H。指令译码器结合时序部件,产生74H操作码的微操作系列,使数字E0H从0001H单元取出。因为指令是要求把取得的数送到A累加器,所以取出的数字经内部数据总线进入A累加器,而不是进入指令寄存器。至此,一条指令的执行完毕。单片机中PC=0002H,PC在CPU每次向存储器取指或取数时自动加1,单片机又进入下一取指阶段。这一过程一直重复下去,直至收到暂停指令或循环等待指令暂停。CPU就是这样一条一条地执行指令,完成所有规定的功能。

来源:网络转载

围观 73

单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。计算机每执行一条指令都可分为三个阶段进行。即取指令-----分析指令-----执行指令。

取指令的任务是:根据程序计数器PC中的值从程序存储器读出现行指令,送到指令寄存器。

分析指令阶段的任务是:将指令寄存器中的指令操作码取出后进行译码,分析其指令性质。如指令要求操作数,则寻找操作数地址。

计算机执行程序的过程实际上就是逐条指令地重复上述操作过程,直至遇到停机指令可循环等待指令。

一般计算机进行工作时,首先要通过外部设备把程序和数据通过输入接口电路和数据总线送入到存储器,然后逐条取出执行。但单片机中的程序一般事先我们都已通过写入器固化在片内或片外程序存储器中。因而一开机即可执行指令。

下面我们将举个实例来说明指令的执行过程:

开机时,程序计算器PC变为0000H。然后单片机在时序电路作用下自动进入执行程序过程。执行过程实际上就是取出指令(取出存储器中事先存放的指令阶段)和执行指令(分析和执行指令)的循环过程。

例如执行指令:MOV A,#0E0H,其机器码为“74H E0H”,该指令的功能是把操作数E0H送入累加器,0000H单元中已存放74H,0001H单元中已存放E0H。当单片机开始运行时,首先是进入取指阶段,其次序是:

1 程序计数器的内容(这时是0000H)送到地址寄存器;

2 程序计数器的内容自动加1(变为0001H);

3 地址寄存器的内容(0000H)通过内部地址总线送到存储器,以存储器中地址译码电跟,使地址为0000H的单元被选中;

4 CPU使读控制线有效;

5 在读命令控制下被选中存储器单元的内容(此时应为74H)送到内部数据总线上,因为是取指阶段,所以该内容通过数据总线被送到指令寄存器。

至此,取指阶段完成,进入译码分析和执行指令阶段。

由于本次进入指令寄存器中的内容是74H(操作码),以译码器译码后单片机就会知道该指令是要将一个数送到A累加器,而该数是在这个代码的下一个存储单元。所以,执行该指令还必须把数据(E0H)从存储器中取出送到CPU,即还要在存储器中取第二个字节。其过程与取指阶段很相似,只是此时PC已为0001H。指令译码器结合时序部件,产生74H操作码的微操作系列,使数字E0H从0001H单元取出。因为指令是要求把取得的数送到A累加器,所以取出的数字经内部数据总线进入A累加器,而不是进入指令寄存器。至此,一条指令的执行完毕。单片机中PC=0002H,PC在CPU每次向存储器取指或取数时自动加1,单片机又进入下一取指阶段。这一过程一直重复下去,直至收到暂停指令或循环等待指令暂停。CPU就是这样一条一条地执行指令,完成所有规定的功能。

来源:网络

围观 440

伪指令不属于单片机的指令系统,而是由汇编器提供的指令,用于调整存储器中程序的位置、定义宏、初始化存储器等。AVR单片机的汇编器共提供18条伪指令(见附表)。

AVR单片机汇编器伪指令

其中,ORG、DB、DW、EQU读者比较熟悉,这里不再赘述。下面对部分伪指令加以说明。
  
BYTE-保存单字节数据到SRAM中。BYTE伪指令仅用在数据存储器。为提供数据保存的位置,在BYTE前应有标号。在由CSEG、ESEG定义的代码段和E2PROM段中不能使用BYTE伪指令。
  
格式LABEL:.BYTE表达式

CSEG-定义程序存储器代码段的起始位置一个汇编文件可以包括若干个代码段,汇编时这些代码段被连成一个代码段。在代码段中不能使用BYTE伪指令。
  
格式.CSEG

DSEG-定义数据段的起始位置一个汇编文件,可以包括若干个数据段,汇编时这些数据段被连成一个数据段。数据段等由BYTE伪指令组成。
  
格式.DSEG

ESEG-定义E2PROM段的起始位置一个汇编文件可以包括若干个E2PROM段,汇编时这些EEPROM段被连成一个EEPROM段。在EEPROM段中不能使用BYTE伪指令。
  
格式.ESE

GDEF-为寄存器设置符号名DEF伪指令允许周符号代替寄存器。一个寄存器可以赋多个符号。
  
格式.DEF符号=寄存器

DEVICE-定义使用的器件DEVICE定义程序所使用的器件,若程序中有指定器件不支持的指令,或程序段、E2PROM段超出指定器件的容量,汇编器将给出提示。若不用DEVICE伪指令,则默认器件支持所有指令,也不限制存储器容量。
  
格式.DEVICEAT90S1200|AT90S2313|AT90S4414|AT90S8515

AVR单片机的器件不同,指令的条数不同。
  
AT90S1200有89条最基本指令;Attinyll/12/15/22有90条指令:AT90S2313/2323/2343/2333/4414/4433/4434/8515/90S8534/8535有118条指令;ATmega603/103有121条指令;ATmega161有130条指令。因此在源程序中必须先用伪指令“DEVICE”定义使用的器件名。
  
INCLUDE-包括另外的文件INCLUDE告诉汇编器从指定的文件开。始读,然后汇编该文件,直至文件结束或遇到EXIT伪指令。
  
格式 INCLUDE“文件名”

EXIT-汇编结束若EXIT出现在包括文件中,则从文件中INCLUDE伪指令行继续执行。

来源: 广电电器

围观 483

单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。计算机每执行一条指令都可分为三个阶段进行。即取指令-----分析指令-----执行指令。

取指令的任务是:根据程序计数器PC中的值从程序存储器读出现行指令,送到指令寄存器。

分析指令阶段的任务是:将指令寄存器中的指令操作码取出后进行译码,分析其指令性质。如指令要求操作数,则寻找操作数地址。

计算机执行程序的过程实际上就是逐条指令地重复上述操作过程,直至遇到停机指令可循环等待指令。

一般计算机进行工作时,首先要通过外部设备把程序和数据通过输入接口电路和数据总线送入到存储器,然后逐条取出执行。但单片机中的程序一般事先我们都已通过写入器固化在片内或片外程序存储器中。因而一开机即可执行指令。

下面我们将举个实例来说明指令的执行过程:

开机时,程序计算器PC变为0000H。然后单片机在时序电路作用下自动进入执行程序过程。执行过程实际上就是取出指令(取出存储器中事先存放的指令阶段)和执行指令(分析和执行指令)的循环过程。

例如执行指令:MOV A,#0E0H,其机器码为“74H E0H”,该指令的功能是把操作数E0H送入累加器,0000H单元中已存放74H,0001H单元中已存放E0H。当单片机开始运行时,首先是进入取指阶段,其次序是:

1 程序计数器的内容(这时是0000H)送到地址寄存器;

2 程序计数器的内容自动加1(变为0001H);

3 地址寄存器的内容(0000H)通过内部地址总线送到存储器,以存储器中地址译码电跟,使地址为0000H的单元被选中;

4 CPU使读控制线有效;

5 在读命令控制下被选中存储器单元的内容(此时应为74H)送到内部数据总线上,因为是取指阶段,所以该内容通过数据总线被送到指令寄存器。

至此,取指阶段完成,进入译码分析和执行指令阶段。

由于本次进入指令寄存器中的内容是74H(操作码),以译码器译码后单片机就会知道该指令是要将一个数送到A累加器,而该数是在这个代码的下一个存储单元。所以,执行该指令还必须把数据(E0H)从存储器中取出送到CPU,即还要在存储器中取第二个字节。其过程与取指阶段很相似,只是此时PC已为0001H。指令译码器结合时序部件,产生74H操作码的微操作系列,使数字E0H从0001H单元取出。因为指令是要求把取得的数送到A累加器,所以取出的数字经内部数据总线进入A累加器,而不是进入指令寄存器。至此,一条指令的执行完毕。单片机中PC=0002H,PC在CPU每次向存储器取指或取数时自动加1,单片机又进入下一取指阶段。这一过程一直重复下去,直至收到暂停指令或循环等待指令暂停。CPU就是这样一条一条地执行指令,完成所有规定的功能。

转自: 21ic电子网

围观 310

单片机执行指令的过程

judy的头像

单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。计算机每执行一条指令都可分为三个阶段进行。即取指令-----分析指令-----执行指令。

取指令的任务是:根据程序计数器PC中的值从程序存储器读出现行指令,送到指令寄存器。

分析指令阶段的任务是:将指令寄存器中的指令操作码取出后进行译码,分析其指令性质。如指令要求操作数,则寻找操作数地址。

计算机执行程序的过程实际上就是逐条指令地重复上述操作过程,直至遇到停机指令可循环等待指令。

一般计算机进行工作时,首先要通过外部设备把程序和数据通过输入接口电路和数据总线送入到存储器,然后逐条取出执行。但单片机中的程序一般事先我们都已通过写入器固化在片内或片外程序存储器中。因而一开机即可执行指令。

下面我们将举个实例来说明指令的执行过程:

开机时,程序计算器PC变为0000H。然后单片机在时序电路作用下自动进入执行程序过程。执行过程实际上就是取出指令(取出存储器中事先存放的指令阶段)和执行指令(分析和执行指令)的循环过程。

MCS- 51系列单片机的指令系统是一种简明高效的指令系统,其基本指令共有111条,其中单字节指令49条,双字节指令4'5条,三字节指令17条。如果按功能可以讲这些指令分为五类:数据传送类(29条)、算术操作类(24条)、逻辑操作类(24条)、控制转移类(17条)以及位变量操作类(17条)。对于反向设计而言,我们关心的不是它的各种具体指令的多少而是指令的寻址方式。所谓的寻址方式就是寻找确定参与操作的数的真正地址。MCS-51系列单片机的111条指令一共只采用了5种寻址方式。5种寻址方式以及它们的寻址空间如表1所示。

基于EDA技术的8051单片机指令系统剖析
表1:表寻址方式及寻址空间

1.寄存器寻址

寄存器寻址方式可用于访问选定寄存器区的8个工作寄存器RO-R7。由指令操作码的低三位指示所用的寄存器,寄存器A, B, DPTR, AB和Cy位(位处理机的累加器)也可作为寻址对象。在这种寻址方式中被寻址的寄存器的内容就是操作数。

在实现这类寻址方式时,确定被寻址寄存器的物理地址时关键。由于选定寄存器区由PSW的相关位来决定,指令的低三位又指示了具体的寄存器,所以可以用下面的VHDL语句来确定相关寄存器的物理地址:

rr_ adr<=unsigned((psw and“00011000”)or(rom_data_i and“00000111”));

其中rr_ adr表示的是寄存器的物理地址,rom_data_i表示的是指令代码。物理地址确定以后,对RAM的操作就很好进行。

2.直接寻址

直接寻址是访问特殊功能寄存器的唯一方法。它也可以用于访问内部RAM(128个字节)。采用直接寻址方式的指令是双字节指令,其中第一个字节是操作码,第二个字节是内部RAM或特殊功能寄存器的直接地址。地址已经给出,显然不需要像寄存器寻址那样先计算地址,直接针对由ROM给出地址就可以对RAM进行相关操作。

3.寄存器间接寻址

寄存器间接寻址可用于访问内部RAM或者外部数据存储器。访问访问内部RAM或者外部数据存储器的低256个字节时,可以采用RO或R1作为间址寄存器。这类指令为单字节指令,其最低为表示采用RO还是R1作为间址寄存器。访问内部RAM和外部数据存储器时采用不同的指令,所以不会引起混淆。

访问外部数据存储器,还可用数据指针DPTR作为间址寄存器,DPTR是16位寄存器,故它可对整个外部数据存储器空Il(64K)寻址。

在执行PUSH(压栈)POP(出栈)指令时,也采用寄存器间接寻址,这时堆栈指针SP用作间址寄存器。

实现这类寻址方式必须分为两步,首先确定4个通用工作寄存器区中可以作为间接寻址寄存器的8个单元的地址,然后读出所选定的寄存器中的值,这个值就是当前指令要寻址的空间的物理地址。确定间接寻址寄存器的地址可以由下面的VHDL语句来实现:

ri_adr<=((psw and“00011000”)or(s-command (7downto 0) and“110000000111”)),

其中ri_ adr表示的是用于间接寻址的寄存器的物理地址,s_command表示的是当前指令的操作码。然后通过另外一个读RAM的进程就可以确定间址寄存器中的值,从而得到指令需要的存储器单元的地址。至千其他特殊功能寄存器作为间址寄存器的情况,由于间址寄存器的地址事先已经能够确定,所以这种方式下寻找存储器单元的地址就仅需要上述两步中的后一个步骤就可以确定指令需要的存储器单元的地址。

4.立即寻址

采用立即寻址方式的指令是双字节的,第一个字节是操作码,第二个字节是立即操作数。因此,这种寻址方式实现起来比直接寻址还要容易,操作数就是放在程序存储器内的常数。

5.基址寄存器加变址寄存器间接寻址

这种寻址方式用于访问程序存储器的一个单元,该单元的地址是基址寄存器(DPTR或PC)与变址寄存器A的内容之和。虽然这类寻址方式也是间接寻址,对于使用DPTR作为基址寄存器的情况,它的实现方法和用数据指针DPTR作为间址寄存器时的间接寻址的情况很相似,因为其间址寄存器事实上还是确定的。与用数据指针DPTR作为间址寄存器时的间接寻址的情况有所不同的是,确认最终需要的地址还要进行一次加法运算,这在使用VHDL语言描述的时候是很容易实现的。用PC作为基址寄存器时,需要知道PC当前值,但是PC和DPTR是不同的,DPTR是特殊功能寄存器,利用它的地址就可以读出其值,PC并没有被分配地址,不能使用读RAM的方式取得其值,所以内部有必要设置编写这样一个进程,它用于读出那些位于CPU内部、没有分配地址的辅助寄存器的值。

来源: EEPW

围观 289

最近在基于51单片机编程的过程中出现了个很奇怪的问题 “程序执行中在寄存器EA=1,ET0=1,TR0=1条件下,单TF0=1时并没有执行中断”。在有过单片机中断编程经历者都知道当EA=1,ET0=1的条件下,满足TF0=1时,如果在此期间没有更高优先级的中断执行的情况下定时器中断0必定会产生中断响应。而在我所编写的程序中仅使用了定时器中断0,一个中断也就谈不上存在优先级问题。

经过我对自己程序的检查并对各教材中断程序对比发现我的程序中的一个问题:由于中断的不可控性决定其跳出中断返回主程序的不确定,而由于程序需要中断跳出后能跳到指定的地址。为了解决这个问题我在中断结束的地方直接用了无条件跳转指令“LJMP ADR16”其中ADR16是我想在中断结束后程序所运行的地址,而没有经过指令“RE”。

问题找到了这就意味着我的程序和其他程序不同的地方就是没有执行“RE”而直接跳出。

为了解决问题所在我查阅了很多单片机方面的资料,教材。几乎所有的教材对指令“RETI”的作用千篇一律都是:“中断程序完成后,一定要执行一条RETI指令,执行这条指令后,CPU将会把堆栈中保存着的地址取出,送回PC,那么程序就会从主程序的中断处继续往下执行了。”如果“RETI”的作用仅仅在于“把堆栈中保存着的地址取出送回PC”;那么我用指令“POP DPH”和“POP DPL”两条指令取代其做用不就可以达到同样的推出地址的效果么?这样可以解决由于只有进堆栈指令(硬件自动生成)没有出堆栈所导致的堆栈溢出错误,但是并不能解决文章开始所提到的“进不了中断”问题。这让我更加相信书上所介绍的关于指令“RETI”作用并不完全。

经过查阅各种资料文献,我发现了个以往在介绍单片机硬件,以及寄存器上教材,老师,没有提及的“‘优先级生效’触发器“的概念。资料指出“根据8051的结构特点,其中断系统中含有两个不可寻址的“优先级生效”触发器。一个用于指出CPU是否正在执行高优先级的中断服务程序,这个触发器为1时,系统将屏蔽所有的中断请求;另一个则指出CPU是否正在执行低优先级中断服务程序,该触发器为1时,将阻止除高优先级以外的一切中断请求。由此可见,若要响应同级甚至是低级中断请求,必须使得该“优先级生效”触发器清零。但该触发器又是不可寻址的,所以无法用软件直接清零。”问题是不是在这里呢?而“优先级生效”触发器清零过程是怎样执行的呢?是在硬件自动执行的那么是在什么时候执行的呢?带着问题我去解决问题。假设我可以将程序满足跳出中断后跳到自己原来指定地址“ADR16”又满足执行指令“RETI”。经过反复思考我用“DEC SP”;“DEC SP”;“MOV DPTR,#ADR16”;“PUSH DPL”;“PUSH DPL”“PUSH DPH”四条指令代替,问题得到了解决。

总结:

中断指令“RETI”做为中断跳出指令除了将堆栈中保存着的地址取出,送回PC;使程序从主程序的中断处继续往下执行。的作用外还有将“优先级生效”触发器清零。自己做的程序也是出现了这个错误,由于对“优先级生效”触发器清零,导致第二次进不了中断(相当于同优先级申请)。

后记:

在解决这个问题时候我所用的知识是课本上的,而又不完全是课本上的。在这个过程中我用已学的知识解决了自己的问题,并进一步推出中断过程的一些新的知识,我认为新知识的学习有很大程度的要靠自己在已学过知识的基础上通过运用,总结,推导等过程获得新知识。着也是当代大学生运用知识,获取新知识的一种能力。

转自: 电子发烧友

围观 410

单片机的正常运行的前提,硬件是一方面,另一方面就是单片机需要执行的程序。大家都知道单片机会执行写好的程序,但是单片机从哪里开始读取指令,数据又被写在了哪里呢?

让我们从最开始的环节讲起。在单片机上电的瞬间,MCU的程序指针PC会被初始化为上电复位时的地址,从哪个地址处读取将要执行的指令,由此程序在MCU上开始执行(当然在调用程序的main之前,还有一系列其他的的初始化要做,如堆栈的初始化,不过这些很少回去修改)。PC在上电时,和MCU差不多,不过读取的是BIOS,有它完成了很多初始化操作,最后,调用系统的初始化函数,将控制权交给了操作系统,于是我们看到了Windows、Linux系统启动了。

如果将操作系统看作是在处理器上奔跑的一个大裸机程序(就是直接在硬件上跑的程序,因为操作系统就是直接跑在CPU上的,这样看待是可以的,不过这个裸机程序功能很多,很强大),那么操作系统的启动很像MCU程序的启动。前者有一个很大的初始化程序完成很复杂的初始化,后者有一段不长的汇编代码完成一些简单的初始化。这一点看,它们在流程上是很相似的。

如果是系统上的程序启动呢?它们是由系统来决定的。Linux上在shell下输入./p后,首先检查是否是一个内建的shell命令;如果不是,则shell假设它是一个可执行文件(Linux上一般是elf格式),然后调用一些相关的函数,将在硬盘上的p文件的内容拷贝到内存(DDR RAM)中,并建立一个它的运行环境(当然这里边还有内存映射,虚拟内存,连接与加载,等一些其他东西),准备执行。

由以上可知,单片机上的程序和平时在系统上运行的程序相比,在启动时差异是很大的(如果将程序调用main以前的动作,都抽象为初始化的话,程序的启动可以简化为:建立运行环境+调用main函数,这样程序的执行差异是不大的)。因为单片机上跑的程序(裸机程序),是和操作系统一样跑在硬件上的,它们属于一个层次的。过去之所以没有区分出单片机上的程序和PC机上的程序的一些差异,就是没有弄明白这一点。

由此,以前的一些疑惑也就解开了。为什么在单片机上的程序不怎么使用malloc,而PC上经常使用?因为单片机上没有已经写好的内存管理算法代码,而在PC上操作系统里运行的程序,libc已经把这些都做了,只需要调用就可以了。如果在单片机上想用动态内存,也可以,但是这些代码要自己去实现,并定义一个相应的malloc,有时候一些公司会提供一些库函数可能会实现malloc,但是因为单片机上RAM内存十分有限,如果不知道它的运行方式,估计会很危险。同样,因为在PC的系统上运行的程序与逻机程序的不同,裸机程序不会有动态链接,有的只是静态链接。

关于程序在执行时,从哪里读取指令,哪里读取数据,也曾因为没有弄清楚系统上的程序和裸机程序之间的区别,而疑惑了很久。虽然在《微型计算机原理》课上知道程序运行时,从内存中读取指令和数据进行执行和回写。但是单片机上只有几K的RAM,而flash一般有几十K甚至1M,这个时候指令和数据都在内存中吗(这里指的内存仅指RAM,因为PC上我们常说的内存就是DDR
RAM memory,先入为主以至于认为单片机上也是这样,还没有明白其实RAM和Flash都是内存)?

这不可能,因为课上老师只说内存,但是PC上内存一般就是DDR RAM,不会是硬盘,硬盘是保存数据的地方;由此类比时,容易把自己弄糊涂,单片机的RAM对应于DDR RAM,那Flash是不是就对应于硬盘了呢?在CSAPP上明白了,PC上之所以都在DDR RAM上,是速度的因素。硬盘的速度太慢,即使是即将到来的SSD比起DDRRAM,还是差着几个数量级,所以拷贝到DDRRAM中。这时,一个程序的代码和数据是连续存放的,其中代码段是只读区域,数据段是可读写区域(这是由操作系统的内存管理机制决定的)。

运行时,再将它们拷贝到速度更快的SRAM中,以得到更快的执行速度。而对于,单片机而言工作频率也就几M或者几十M,从Flash中与从RAM中读的差异可能并不明显,不会成为程序执行的瓶颈(而对于PC而言,Flash的速度太慢,DDRRAM的速度也是很慢,即使是SRAM也是慢了不少,于是再提高工作频率也提高不了程序的执行速度,所以现在CPU工作频率最快是在2003左右。一个瓶颈出现了。为了提高CPU的使用率,换个角度想一下,既然不能减少一段程序的执行时间,就在同样的时间执行更多的程序,一个核执行一段程序,两个核就可以执行两段程序,于是多核CPU成为了现在的主流)。

所以裸机程序指令就在Flash(Flash memory)中存放,而数据就放在了RAM中(flash的写入次数有限制,同时它的速度和RAM还是差很多)。更广泛说,在单片机上RAM存放data段、bss段、堆栈段;ROM(EPROM、EEPROM、Flash等非易失性存储设备)存放代码,只读数据段。本质上说,这和PC上程序都在RAM中存放是一样的,PC 上是操作系统规定了可读与可写,而单片机上是依靠不同的存储设备区分了可读与可写。当然现在的Flash是可读写的,如果Flash没有写入次数限制,速度又可以和RAM相差不多,单片机上是不是只要Flash就可以了呢(直接相当于PC上的DDRRAM)?这样成本也会比一个RAM,一个Flash低,更节省成本,对于生产商更划算。

对于单片机的程序执行时指令和数据的存放与读取,理解如下:

放在Flash中。当单片机上电后,初始化汇编代码将data段、bss段、复制到RAM中,并建立好堆栈,开始调用程序的main函数。以后,便有了程序存储器,和数据存储器之分,运行时从Flash(即指令存储器,代码存储器)中读取指令 ,从RAM中读取与写入数据。RAM存在的意义就在于速度更快。

无论是单片机也好,PC也罢,存在的存储器金字塔都是一致的,速度的因素,成本的限制导致了一级级更快的存储器的更快速度与更高的成本。应该说,对于它们的理解,就是存储器金字塔的理解。

本篇文章没有讲解单片机程序的相关写法,而是关注了更为基础的方面:单片机指令的读取和数据存放的位置。看多了单片机程序写法的朋友不妨阅读一下本篇文章,或许能从中找到一些解决单片机程序错误的方法。

来源:互联网(版权归原著作者所有)

围观 334
订阅 RSS - 指令