1. 程式人生 > >ARM學習筆記——異常與中斷——指令ldr及.word偽指令用法

ARM學習筆記——異常與中斷——指令ldr及.word偽指令用法

在ARM彙編指令中,ldr是一條常用的記憶體訪問指令,如:

ldr r1, [r2] //將地址為r2的記憶體單元位資料讀取到r1中

它也可以作為大範圍的地址讀取偽指令,如:

    ldr r1, =label        //r1=label的地址
label:
    ……

這裡有一個問題,ldr偽指令是怎麼得到label的地址?通過檢視反彙編檔案,可以看到以下程式碼:

/* ldr pc, =do_und */
30000004:	e59ff0b0 	ldr	pc, [pc, #176]	; 300000bc <.text+0xbc>

/* do_und在反彙編檔案中的位置 */
30000008 <do_und>:
            ……

從上面看出,使用ldr偽指令時,他並不是直接把label的地址傳給r1,而是到一個地址為300000bc的地方讀取資料,而300000bc存放著label的地址:

/* 3000000bc存放label的地址 */
300000bc:	30000008 	andcc	r0, r0, r8

由上面可以知道ldr偽指令讀取地址時回到程式的某個地方去讀取地址,而這個地方編譯器會安排在程式的後面。2440片內sram只有4k,如果此時程式大於4k,並且遇到了異常,那將會出現讀不到資料的情況,為了讓程式直接獲取異常處理函式的地址,此時可以藉助.word偽指令:

/* 在label的地方放一個word型別的資料:expression */
label:
    .word expression
/* 此處使用ldr指令,不是偽指令 */
    ldr pc, addr_und 
/* 使用.word,在此處存放do_und地址 */
addr_und:
	.word do_und	
do_und:
    ……

經過修改後再來看看反彙編

30000004:	e51ff004 	ldr	pc, [pc, #-4]	; 30000008 <addr_und>
30000008 <addr_und>:
30000008:	3000000c 	andcc	r0, r0, ip
3000000c <do_und>:

現在程式不會跳到後面去讀取地址了