2.4.3.局部变量

函数中的局部变量放在堆栈上。编译器使用 SP 寄存器来访问这些局部变量。函数的堆栈帧由局部变量和其他编译器生成的数据组成。对于大小超过 63 个字(SP 偏移寻址模式的最大范围)的帧,编译器使用 XAR2 作为帧指针 (FP)。

若要利用 SP 相对寻址,请保持局部帧少于 64 个字。表 2.5 说明了堆栈帧大小对所生成代码效率的影响。两个代码片段之间的唯一区别是,在左边的示例中,堆栈帧大于 64 个字。在此示例中,volatile 用于确保编译器从存储器中读取局部变量 ab,而不是将它们分配给寄存器

表 2.5 所生成代码的堆栈帧大小和效率
堆栈帧 >= 64 个字 堆栈帧 < 64 个字
int16_tlocal_variables1(){volatileint16_ta;int16_tarray[64];volatileint16_tb;a=42;b=44;update(array,64);returna+b;}
int16_tlocal_variables2(){volatileint16_ta;int16_tarray[32];volatileint16_tb;a=42;b=44;update(array,32);returna+b;}

表 2.6 说明了当帧大小小于 64 字时,编译器如何能够使用更高效的 SP 相对寻址。

表 2.6 所生成代码的结构大小和效率
帧大小 >= 64 需要使用 FP (AR2) 帧大小 < 64 使用 SP 相对寻址
||local_variables1||: MOVL *SP++,XAR1 MOVL *SP++,XAR2 MOVZ AR2,SP SUBB FP,#6 ADDB SP,#66 MOVZ AR4,SP MOVB *+FP[7],#42,UNC MOVB AL,#64 SUBB XAR4,#64 MOVB *+FP[6],#44,UNC MOVZ AR4,AR4 LCR #||update|| MOV AL,*+FP[6] ADD AL,*+FP[7] SUBB SP,#66 MOVL XAR2,*--SP MOVL XAR1,*--SP LRETR
||local_variables2||: ADDB SP,#34 MOVZ AR4,SP MOVB *-SP[33],#42,UNC MOVB AL,#32 SUBB XAR4,#32 MOVB *-SP[34],#44,UNC MOVZ AR4,AR4 LCR #||update|| MOV AL,*-SP[34] ADD AL,*-SP[33] SUBB SP,#34 LRETR