嵌入式 8051 的堆栈和堆混淆

Cal*_*ian 3 c memory embedded 8051

我试图了解有关 8051 MCU 架构内存布局的一些基本概念。如果有人能给我一些澄清,我将不胜感激。

因此,对于 8051 MCU,我们有几种类型的存储器:

  • IRAM - (idata) - 用于通用寄存器和 SFR

  • PMEG - (code) - 用于存储代码 - (FLASH)

  • 扩展数据

    • 片上(数据) - 数据高速缓冲存储器(RAM)/
    • 片外 (xdata) - 外部存储器 (RAM)

问题:

  1. 那么堆栈实际上位于哪里?我假设在 IRAM (idata) 中,但它非常小 (30-7Fh) - 79 字节

  2. 堆栈有什么作用?

    现在,一方面,我读到它在我们调用函数时存储返回地址(例如,当我调用函数时,返回地址存储在堆栈上并且堆栈指针递增)。

    http://www.alciro.org/alciro/microcontroladores-8051_24/subrutina-subprograma_357_en.htm

    另一方面,我读到堆栈存储函数中的局部变量,一旦我们从该函数返回,这些变量就会被“删除”。 http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html

  3. 如果我使用动态内存分配(堆),该内存是否始终保留在片外 RAM(xdata)中,还是取决于编译器/优化?

too*_*ite 5

8051起源于 20 世纪 70 年代/80 年代初因此,它的资源非常有限。原始版本(例如)甚至没有 XRAM,后来被“修补”到一边并需要特殊(且缓慢)访问。

IRAM 是“主存储器”。它确实包括堆栈(是的,只有几个字节)。其余部分用于全局变量(“data”和“bss”部分:已初始化和未初始化的全局变量和静态变量)。出于同样的原因,编译器可能会使用 XRAM。请注意,对于这些小型 MCU,您不会使用很多局部变量(如果仅使用 8 位类型)。一个聪明的编译器/链接器(我实际上使用了其中一些)可以静态重叠地分配局部变量 - 除非使用递归(非常不可能)。

最值得注意的是,此类系统的程序大多不使用堆(即动态内存分配),而仅使用静态分配的内存。最多,他们可能使用内存池,它提供固定大小的块并且不合并块。

请注意,IRAM 包括一些可由硬件进行位寻址的特殊寄存器。通常,您会使用可以利用这些函数的专用编译器。某些功能很可能需要特殊的汇编函数(这些函数可能在标头中作为 C 函数提供,只是生成相应的机器代码指令),称为内在函数。

不同的内存区域可能还需要使用编译器扩展。您可以查看sdcc来寻找合适的编译器。

另请注意,8051 具有扩展的哈佛架构(代码和数据与 XRAM 作为第 3 方分离)。

关于您的第二个链接:这是一篇非常笼统的文章;它不涵盖像 8051(或 AVR、PIC 等)这样的 MCU,而是更通用的 CPU,如 x86、ARM、PowerPC、MIPS、MSP430(也是更小的 MCU)等,使用外部冯·诺依 架构(在内部,大多数(如果不是全部)32+ 比特币都使用哈佛架构)。