Compiler construction AVR XYZ寄存器

Compiler construction AVR XYZ寄存器,compiler-construction,microcontroller,avr,ram,Compiler Construction,Microcontroller,Avr,Ram,AVR微控制器中X、Y和Z寄存器的区别是什么。它们中的哪一个适合C编译器?编译器在哪里存储堆指针、堆栈指针、帧指针?该寄存器是否具有相同的功能或在不同的空间(例如EEPROM、RAM)中提供寻址。

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

ld r16, X
使用后增量或预减量:

ld r16, -Y
st Z+, r16
但只有Y和Z可以与位移一起使用

ldd r16, Y + 10
std Z + 5, r16
且只有Z可用于间接读取闪存,且无预减量或位移:

lpm r16, Z+
lpm r17, Z
因此,编译器没有特定的方式来使用它们,也没有特定的方式来存储哪些信息。考虑到所有这些限制,它非常依赖于编译器。 例如,Z可以保留以访问闪存,而Y可以存储堆栈帧,因为它可以通过置换来访问。 同样例如,GCC使用X和Z寄存器作为“由调用方保留”,而Y寄存器作为“由被调用例程保留”。此约定有助于最小化推送弹出操作,允许调用方例程将Y分配为指针迭代器或堆栈帧,还允许被调用例程自由使用X和Z,而无需花费时间来推送和弹出它们。 但同样,如何使用这些寄存器取决于编译器。没有任何东西强迫它以这样或那样的方式使用寄存器

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


AVR中没有堆这样的东西。所以,如果编译器以某种方式实现堆内存管理,它取决于堆在何处以及如何分配的实现。但说到像AVR这样的小型MCU,通常根本没有存储堆的意义,因为不需要动态分配。

对不起,我的意思是数据堆栈指针不调用堆栈。它存储在哪里?为什么说AVR MCU对于动态内存分配来说太小了。MEGA和XMEGA中的一些具有从4KB到16KB的内部RAM,并且可以使用外部RAM内存。只有一个堆栈。它既用于存储返回地址(call/ret),也用于存储数据(保留寄存器push/pop和局部变量)。是的,可以有一个内存管理器。但大多数任务中,MCU不需要这样做。快速响应和可预测的内存分配比内存管理器的不可预测行为要好,内存管理器的不可预测行为可能导致堆碎片和堆栈重叠所有在堆栈或寄存器中分配的局部变量。它取决于编译器,甚至取决于所选的优化级别。如果没有显式启用的内存管理器来拥有堆和显式分配的内存(例如malloc),则不会在其中存储任何变量。@实际上,由于AVR上的处理器堆栈仅支持单寄存器的推送和弹出,因此有些编译器仅将此堆栈用于返回地址,并牺牲一个指针寄存器来实现本地数据的单独堆栈。