Arm匯編學習筆記(四)——ARM的37個寄存器和異常處理

ARM 484瀏覽

 

1. Arm的37個寄存器

看下面這張圖:
可以看到User和System模式下的R0~R15和CPSR都是相同的寄存器,而在其它特權模式下用灰色三角形標注的那些寄存器,是該特權模式下特有的寄存器,比如在User模式下存入R8值0x50,切換到FIQ模式下存入R8值0x100,再切換回User模式下后,R8寄存器的值還是0x50。
這樣算一下R0~R15在加上CPSR,然后在加上圖中所有灰色三角標注的寄存器的個數正好是37個。

2. 異常處理

Arm在執行指令的過程中如果遇到異常,會跳轉到異常向量表中對應的位置去處理,這里只是介紹異常向量表的作用,以及遇到異常后的執行流程。
異常向量表是約定好了的,但是異常向量表的內容是可以改變的,其定義如下:
上圖對應了各種異常的情況下,程序跳轉的地址。例如如果出現未定義的指令時,系統會切換到UND為定義模式,并跳轉到0x00000004位置去執行,然而那個位置只有四字節可以執行,實際上那個位置只是一條跳轉指令,會跳轉到真正的處理函數,而這個真正的處理函數就叫做stub。
舉個例子,加入我們在開發板上作業的話,就可以將下面內容放到0x0起始地址處,來實現自己的異常處理:
	b reset
	b und
	b swi
	b abt_pre
	b abt_dat
	.word 0
	b irq
	b fiq
 
 
 
 
reset:
	@stub, TODO
 
und:
	@stub
	adr r0, str
	ldr r3, printf
	mov lr, pc
	mov pc, r3
 
 
swi:
	@stub, TODO
 
abt_pre:
	@stub, TODO
 
abt_dat:
	@stub, TODO
 
irq:
	@stub, TODO
 
fiq:
	@stub, TODO
 
 
.extern printf
 
str:
	.asciz “undefined instr.\n”
上面代碼只是為了實驗,所以只實現了UND的處理函數stub,其它的只是聲明了一下。在0x00000000處的指令是"b reset",會跳轉到reset標簽的位置去執行;而0x00000004處的指令是"b und",當發生未定義指令異常的時候就會跳轉到und標簽位置去處理了,這里我們只是輸出了一個字符串"undefined instr."。
那么什么情況下會出現未定義指令異常呢?例如下面代碼中的0x7777777
.global main
 
main:
	mov ip, sp
	stmfd sp!, {fp, ip, lr, pc}
	sub fp, ip, #4
 
	.word 0x77777777
 
	sub sp, fp, #12
	ldmfd sp!, {fp, sp, pc}

將上面代碼編譯成可執行文件后,用arm-linux-androideabi-objdump -d命令把反匯編得到下面內容:

00000234 <main>:
 234:	e1a0c00d 	mov	ip, sp
 238:	e92dd800 	push	{fp, ip, lr, pc}
 23c:	e24cb004 	sub	fp, ip, #4
 240:	77777777 			; <UNDEFINED> instruction: 0x77777777
 244:	e24bd00c 	sub	sp, fp, #12
 248:	e8bda800 	pop	{fp, sp, pc}

可以看到0x7777777是一條未定義指令,系統就會產生未定義異常。

上面的內容具體可以看視頻:http://v.youku.com/v_show/id_XNTQ0MDk2MjAw.html?f=19177600&from=y1.2-3.4.5

 

七星彩走势图2元网官网