1. 程式人生 > >ARM區域性變數初始化

ARM區域性變數初始化

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到目標暫存器中。