新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Android ARM 指令學(xué)習(xí)

Android ARM 指令學(xué)習(xí)

作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
6.1原生程序ARM匯編語言,逆向你的helloworld
6.2原生程序的生成過程
1:預(yù)處理
“如include頭文件"包含的頭文件全部編譯進(jìn)來,還有#define預(yù)定義,#if預(yù)條件處理等也都在這里被編譯器處,詳細(xì)的輸出可以給gcc編譯器傳遞”-E“,選項(xiàng)查看。
2,編譯
編譯器首先要檢查代碼的規(guī)范性,以及是有語法錯(cuò)誤等,以及代碼實(shí)際要做的工作,檢查無誤后,gcc編譯器把代碼翻譯成ARM匯編語言代碼,可以為gcc編譯器傳遞”-S“選項(xiàng)查看輸出,執(zhí)行”gcc-s hello.i“ -o hello.s 后生成hello.s匯編文件。
3,匯編
這個(gè)階段會(huì)調(diào)用連接器將匯編成二進(jìn)制文件的目標(biāo)文件,以上一小節(jié)的hello為例,執(zhí)行”gcc-c hello.s -o hello.o“ 后生成hello.o目標(biāo)文件。
4,連接
這個(gè)階段編譯器會(huì)調(diào)用連接器將二進(jìn)制的目標(biāo)文件連接成Android平臺(tái)可執(zhí)行的ARM原生程序,以上一個(gè)小節(jié)為hello為例,執(zhí)行g(shù)cc hello.o -o hello 后會(huì)生成hello可執(zhí)行文件。
6.2.3必須要了解的ARM知識(shí)
總結(jié):
1:c語言編寫代碼在編譯時(shí)有一個(gè)過程,是將其轉(zhuǎn)換成ARM匯編代碼,所以可以這么理解,c語言實(shí)現(xiàn)的功能ARM
匯編語言都能實(shí)現(xiàn)。
2,ARM匯編語言中特有的寄存器。寄存器是處理特有的高速存儲(chǔ)部件,它們可以用來暫存指令,數(shù)據(jù)和位址,高級(jí)語言用到中用到的變量,常量,結(jié)構(gòu)體,類等數(shù)據(jù)用到了ARM匯編語言中,就是使用寄存器保存的值或內(nèi)存地址,寄存器的數(shù)據(jù)量有限,ARM微處理器共有37個(gè)32位寄存器,其中31個(gè)為通用寄存器,6個(gè)為狀態(tài)寄存器,ARM處理器器支持7中運(yùn)行模式。
1;用戶模式(usr)ARM 處理器正常的程序執(zhí)行狀態(tài)。
2;快速中斷模式(fiq):用與高速數(shù)據(jù)傳輸或通道處理
3;外部中斷模式(irp)用于通用的中斷處理。
4;管理模式(svc)操作系統(tǒng)使用的保護(hù)模式
5;數(shù)據(jù)訪問終止模式(abt);當(dāng)數(shù)據(jù)或指令預(yù)取終止進(jìn)入該模式,可用于虛擬存儲(chǔ)及存儲(chǔ)數(shù)據(jù)。
6;系統(tǒng)模式(sys):運(yùn)行具有特權(quán)的操作系統(tǒng)任務(wù)。
7;未定義指令終止模式(und):當(dāng)未定義的指令執(zhí)行時(shí)進(jìn)入該模式。
Thumb是ARM體系結(jié)構(gòu)中一種16位的指令集。
從ARMv4T之后的ARM處理器有一種16-bit指令模式,叫做Thumb,也許跟每個(gè)條件式執(zhí)行指令均耗用4位元的情形有關(guān)。Thumb指令集可以看作是ARM指令壓縮形式的子集,它是為減小代碼量而提出,具有16bit的代碼密度。Thumb指令體系并不完整,只支持通用功能,必要時(shí)仍需要使用ARM指令,如進(jìn)入異常時(shí)。其指令的格式與使用方式與ARM指令集類似,而且使用并不頻繁,Thumb指令集作一般了解
ARM匯編語言程序結(jié)構(gòu)
1.一個(gè)完整的ARM匯編指令包括處理器架構(gòu)定義,數(shù)據(jù)段,代碼與main函數(shù)。
2.段定義.data的數(shù)據(jù)段中,
如果細(xì)分的話,
.rodata的只讀數(shù)據(jù)段中,這些數(shù)據(jù)段不可以執(zhí)行的。
.text的代碼段中ARM匯編使用,
".section"指令來定義段
.section name
3.注釋與標(biāo)號(hào)
/*...*/
4.匯編器指令
程序中所有以“.”開頭的指令都是匯編指令,
.file:指定了源文件名,實(shí)例hello.s是從hello.c編譯得來的,手寫匯編代碼可以忽略。
.align:指定了代碼的對(duì)齊方式,后面跟的數(shù)值為2的次方,如:“.align4” 表示2^4=16個(gè)字節(jié)對(duì)齊
.ascii:聲明全局符號(hào)。全局符號(hào)是指在本程序外可以訪問的符號(hào)。
.global:聲明全局符號(hào)。全局符號(hào)是指在本程序外可以訪問的符號(hào)。
.type:指定符號(hào)的類型。“.type main,%function ” 表示main符號(hào)為函數(shù)。
.word:用來存儲(chǔ)地址址。"word. LCD-(LPIC0+8)"存放的是一個(gè)與地址無關(guān)的偏移量,
.size:設(shè)置指定符號(hào)的大小。“.size main ,-.main”中的點(diǎn),“.表示當(dāng)前地址”,減去main符號(hào)的地址即為整個(gè)
main符號(hào)的地址即為整個(gè)main函數(shù)的大小。
5.子線程與參數(shù)傳遞
.global 函數(shù)名
.type 函數(shù)名 ,%function 函數(shù)名
函數(shù)名
<....函數(shù)體...>
例如聲明一個(gè)實(shí)現(xiàn)兩個(gè)數(shù)相加的函數(shù)的代碼為:
.global MyAdd
.type MyAdd,%function
MyAdd:
ADD:r0, r0,r1 @ 兩個(gè)數(shù)相加
mov pc,lr@函數(shù)返回
ARM匯編中規(guī)定,R0-R3這4個(gè)寄存器用來傳遞函數(shù)調(diào)用的第1到第4個(gè)參數(shù),超出的參數(shù)通過堆棧來傳遞。R0同時(shí)用來存放函數(shù)調(diào)用的返回值,被調(diào)用的函數(shù)在返回前無需這些寄存器的內(nèi)容。
6.4寄存器
1,立即尋址
MOV R0 ,#1234 指令執(zhí)行后,R0=1234,立即數(shù)“#作為前綴",表示十六進(jìn)制數(shù)值時(shí)以”0x“開頭
2,寄存器尋址
MOV R0 ,R1 寄存器尋址中,操作數(shù)的值在寄存器,指令執(zhí)行時(shí)直接從寄存器中取值進(jìn)行操作
3,寄存器移位尋址
LSL :邏輯左移->移位后寄存器空出的低位補(bǔ)0
LSR:邏輯右移->移位后寄存器空出的高位補(bǔ)0
例如:
MOVR0 ,R1,LSL #2 表示:指令的功能是將R1寄存器左移2位,即“R1<<2” 后賦值給R0寄存器,指令執(zhí)行后R0=R1*4;
4,寄存器間接尋址
例如:寄存器間接尋址碼給出寄存器是操作數(shù)的地址指針,所需的操作數(shù)保存在寄存器指定地址的存儲(chǔ)單元
中,
例如:
LDRR0 ,[R1]
指令功能是將R1寄存器的數(shù)值作為地址,取出地址中的值賦值給R0寄存器。
5,基址尋址
基址尋址是將地址碼給出的寄存器與偏移量相加,形成操作數(shù)的有效地址,所需的操作數(shù)保存在有效地址所指向的存儲(chǔ)單元中,基址尋址多用于查表,數(shù)組訪問等操作,
例如:LDRR0 ,[R1,#-4]
指令的功能是 將R1寄存器的數(shù)值減4作為地址,取出此地址的值賦值給R0寄存器。
6,多寄存器尋址
多寄存器尋址一條指令最多可以完成16個(gè)通用寄存器值得傳遞
LDMIAR0,{R1,R2,R3,R4}
LDM是數(shù)據(jù)加載指令,指令的后綴IA表示每次執(zhí)行完加載操作后R0寄存器的值自增1個(gè)子,ARM中一個(gè)字表示的是一個(gè)字的32位數(shù)字(bit),這條指令執(zhí)行后,R1=[R0],R2=[R0+#4]
R3=[R0+#8],R4=[R0+#12]
7,堆棧尋址
堆棧尋址是ARM處理器特有的一種尋址方式,堆棧尋址需要使用特定的指令來完成
堆棧尋址的指令由LDMFA/STMFA,LDMEA/STMEA,LDMFD/STMFD
FA,EA,FD,ED 為指令前綴,表示多寄存器尋址,即一次可以傳遞多個(gè)寄存器值,F(xiàn)A,EA,FD,ED,為后綴
堆棧尋址舉例:
STMFD SP! {R1-R7,LR} @將R1~R7,LR入棧,多用于保持子線程“現(xiàn)場(chǎng)”
LDMFD SP! {R1-R7,LR} @將數(shù)據(jù)出棧,放入R1~R7,LR寄存器,恢復(fù)子程序“現(xiàn)場(chǎng)”
8,塊拷貝尋址
塊拷貝尋址可以實(shí)現(xiàn)連續(xù)地址數(shù)據(jù)從寄存器的莫某一位置拷貝到另一位置,
塊拷貝尋址的指令由
LDMIA/STMIA,LDMDA/STMDA/LDMIB/STMIB
LDM和STM為指令前綴,表示多寄存器尋址,即一次可以傳遞多個(gè)寄存器值,IA,DA,IB,DB為后綴,
塊拷貝舉例
LDMIA R0! ,{R1-R3} @從R0寄存器指向的存儲(chǔ)單元中讀取3個(gè)子到R1-R3寄存器
STMIA R0! ,{R1-R3} @存儲(chǔ)R1-R3寄存器的內(nèi)容到R0寄存器指向的存儲(chǔ)單元
9,相對(duì)尋址
相對(duì)尋址以程序計(jì)數(shù)器PC當(dāng)前值為級(jí)地址,指令中的地址中的標(biāo)號(hào)作為偏移量,將兩者相加后得到操作數(shù)的有效地址
BL NEXT
...
NEXT :
....
BL NEXT 是跳轉(zhuǎn)到NEXT標(biāo)號(hào)處執(zhí)行,這里BL采用的就是相對(duì)尋址,標(biāo)號(hào)NEXT 就是偏移量。
待續(xù)...


關(guān)鍵詞: AndroidARM指令學(xué)

評(píng)論


技術(shù)專區(qū)

關(guān)閉