ARM區域性變數初始化
阿新 • • 發佈:2019-02-09
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到目標暫存器中。