compiler-construction - AVR XYZ 寄存器

标签 compiler-construction microcontroller avr ram

AVR 微 Controller 中的 X、Y 和 Z 寄存器有什么区别。他们每个人适合 C 编译器的是什么?编译器在哪里存储堆指针、堆栈指针、帧指针?该寄存器是否具有相同的功能或在不同空间(例如 EEPROM、RAM)中提供寻址。

最佳答案

X Y 和 Z 寄存器实际上是一对 r27:r26、r29:r28 和 r31:r30 寄存器。它们中的每一个都可以用作指向 SRAM 的间接指针:

ld r16, X

后递增或前递减:

ld r16, -Y
st Z+, r16

但是只有Y和Z可以用位移

ldd r16, Y + 10
std Z + 5, r16

而且只有Z可以用来间接读flash memory,不能预减或位移:

lpm r16, Z+
lpm r17, Z

因此,编译器应该如何使用它们以及应该存储哪些信息没有特定的方式。考虑到所有这些限制,它非常依赖于编译器。 比如Z适合用来访问flash memory,而Y适合用来存放stack frame,因为可以位移访问。 又例如,GCC 将 X 和 Z 寄存器用作“由调用者保留”,而 Y 寄存器用作“由被调用例程保留”。此约定有助于最大限度地减少压栈操作,允许调用例程将 Y 分配为指针迭代器或堆栈帧,还允许被调用例程自由使用 X 和 Z 而无需花费时间来压栈和弹出它们。 但是同样,如何使用这些寄存器在很大程度上取决于编译器。没有任何东西强制它以这种或那种方式使用寄存器。

堆栈指针 始终存储在 SPH:SPL I/O 寄存器(0x3E、0x3D)中,它们由内核本身处理,同时执行调用、返回、压入和弹出。编译器不需要将其存储在其他地方。

在 AVR 中没有这样的东西。因此,如果编译器以某种方式实现堆内存管理,则取决于堆分配位置和方式的实现。但是对于像 AVR 这样的小型 MCU,通常根本没有存储堆的意义,因为不需要动态分配。

关于compiler-construction - AVR XYZ 寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48645379/

相关文章:

compiler-construction - Haskell 编译器如何处理 'where' 语句?

c - 如何使用 verilog PLI 通过 ncverilog 编译器与 c 通信

compiler-construction - 如何开始编写翻译器?可能吗

c - n/=10 和 n=n/10 的区别

c - 人们使用Pic和c进行计数器

c - 关于嵌入式 C 中的定时器

c - ((void(*)(void))0)() 是 Exit 函数吗?

compiler-construction - 词法分析器的目的是什么?

c - void osSleep(tU32 ticks) - 它是如何工作的(微 Controller 中的定时器)?

c - AVR MCU 崩溃,代码中没有逻辑错误。我应该检查什么?