1、函数内部的局部变量如何初始化,如以下程序中的cost_a、const_b、const_c:
extern int main( void )
{
uint32_t const_a = 0x12345678;
uint32_t const_b = 0x87654321;
uint32_t const_c = 0x04;
while(1)
{
fun_a(const_a, const_b, const_c);
fun_b(const_a, const_b, const_c, 123, 1234567);
}
}
2、编译后,对应的汇编文件片段如下:
// 107 extern int main( void )
// 108 {
main:
PUSH {R4-R6,LR}
CFI R14 Frame(CFA, -4)
CFI R6 Frame(CFA, -8)
CFI R5 Frame(CFA, -12)
CFI R4 Frame(CFA, -16)
CFI CFA R13+16
SUB SP,SP,#+8
CFI CFA R13+24
// 109 uint32_t const_a = 0x12345678;
LDR R4,??DataTable0 ;; 0x12345678
// 110 uint32_t const_b = 0x87654321;
LDR R5,??DataTable0_1 ;; 0x87654321
// 111 uint32_t const_c = 0x04;
MOV R6,#+4
// 112
// 113 while(1)
// 114 {
// 115 fun_a(const_a, const_b, const_c);
??main_0:
MOVS R2,R6
MOVS R1,R5
MOVS R0,R4
CFI FunCall fun_a
BL fun_a
// 116 fun_b(const_a, const_b, const_c, 123, 1234567);
LDR R0,??DataTable0_2 ;; 0x12d687
STR R0,[SP, #+0]
MOV R3,#+123
MOVS R2,R6
MOVS R1,R5
MOVS R0,R4
CFI FunCall fun_b
BL fun_b
B ??main_0
CFI EndBlock cfiBlock2
// 117 }
// 118 }
SECTION `.text`:CODE:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, 0
DATA
??DataTable0:
DC32 0x12345678
SECTION `.text`:CODE:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, 0
DATA
??DataTable0_1:
DC32 0x87654321
其中:
// 109 uint32_tconst_a = 0x12345678;
LDR R4,??DataTable0 ;; 0x12345678
// 110 uint32_tconst_b = 0x87654321;
LDR R5,??DataTable0_1 ;; 0x87654321
// 111 uint32_tconst_c = 0x04;
MOV R6,#+4
说明在main函数中,使用R4、R5、R6分别保存局部变量const_a、const_b、const_c,并且使用LDR指令、MOV指令来初始化局部变量。LDR指令是寄存器加载指令,LDR指令将内存中指定地址的内容加载到目标寄存器,如上面所示,内存中指定的地址是??DataTable0、??DataTable_1,这些地址对应的内容就是局部变量的初始值:
SECTION `.text`:CODE:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, 0
DATA
??DataTable0:
DC32 0x12345678
SECTION `.text`:CODE:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, 0
DATA
??DataTable0_1:
DC32 0x87654321
另外,局部变量const_c,则是使用MOV指令初始化,因为其初始值0x04可以使用MOV指令中的立即数字段表示。若初始值不能使用立即数表示、或者不能通过立即数移位的形式得到,则使用LDR指令完成。
3、
// 109 uint32_t const_a = 0x12345678;
LDR R4,??DataTable0 ;; 0x12345678
// 110 uint32_t const_b = 0x87654321;
LDR R5,??DataTable0_1 ;; 0x87654321
// 111 uint32_t const_c = 0x04;
LDR指令在寻址时,使用[PC+offset]的形式计算PC相关的内存地址,然后从内存中加载32bit到目标寄存器中。