android arm 寄存器,ARM汇编
8種機(jī)械鍵盤軸體對(duì)比
本人程序員,要買一個(gè)寫代碼的鍵盤,請(qǐng)問紅軸和茶軸怎么選?
Android Native 進(jìn)程啟動(dòng)流程
ARM傳參,R0-R3傳遞前四個(gè)參數(shù)
1. Thumb 指令集特點(diǎn)Thumb 指令集指令長度:16或32,16為為主
Thumb-16 大部分只能訪問前8個(gè)寄存器 R0-R7(少數(shù)可以訪問R8-R15)
Thumb-32 可以訪問所有的ARM core 寄存器 R0-R15
更小、更加靈活
2. ARM指令集特點(diǎn)指令長度32位,4字節(jié)對(duì)齊
功能更加完善
對(duì)比ThumbARM2字節(jié)對(duì)齊4字節(jié)對(duì)齊
占用空間少、密度高占用空間較多
功能不齊全功能齊全
ARM和Thumb指令集各有自己的優(yōu)點(diǎn),取長補(bǔ)短往往會(huì)得到最好的性能
3. Opcod 中判斷指令集Opcode[15:13]== 111 && Opcode[12:11]!= 00 滿足則為32bit 的ARM
bl #0x80000fbc
0xed 0xff 0xff 0xeb
4. IDA 中識(shí)別與切換指令集Edit->segments->change segment register value(快捷鍵ALT+G)
請(qǐng)看操作。
這有一段指令,判斷出目前是thumb指令集的
按下ALT+G,把0x1改成0x0,就是指定為ARM指令集
然后按下P鍵定義函數(shù),函數(shù)參數(shù)就都分析出來了(
5. ARM切換指令集原理處理器無論在ARM還是Thumb狀態(tài)下都可以通過BX/BLX/LDR/LDM切換不同的指令集。
狀態(tài)切換是由寄存器Rn的最低位來指定的,如果操作數(shù)寄存器的狀態(tài)位Bit0=0,則進(jìn)入ARM狀態(tài),如果Bit0=1,則進(jìn)入Thumb狀態(tài)。
ARM 中對(duì)于字節(jié)、字、雙字的定義
注意和intel匯編的區(qū)別,一個(gè)word(字)這里是4個(gè)字節(jié)
但是注意一下,在IDA中依然延續(xù)著老的傳統(tǒng),一個(gè)DCW(word)代表兩個(gè)字節(jié)DCB 定義1字節(jié)數(shù)據(jù)
DCW 定義2字節(jié)數(shù)據(jù)
DCD 定義4字節(jié)數(shù)據(jù)
在IDA中,在上面這些數(shù)據(jù)定義上按下D鍵可以切換定義的類型
Array 定義數(shù)組,右鍵或*號(hào)鍵
數(shù)組最常見的就在數(shù)組,
IDA中的自定義數(shù)據(jù)類型
Structures 窗口中可以創(chuàng)建一個(gè)自定義結(jié)構(gòu)體。按下I或者Ins鍵即可創(chuàng)建。
創(chuàng)建了一個(gè)名為test的結(jié)構(gòu)體
因?yàn)闆]有定義字段,所以現(xiàn)在都還是空的,結(jié)構(gòu)體長度為0(相當(dāng)于空結(jié)構(gòu)體,沒有任何內(nèi)容)
所以去定義字段。
為自定義數(shù)據(jù)類型添加字段
創(chuàng)建完結(jié)構(gòu)體后,長這樣:
在ends處按下D鍵就可以定義一個(gè)字段了,在字段上按D可以改變長度1/2/4
其他按鍵:
這樣就可以給一個(gè)變量轉(zhuǎn)成自己的結(jié)構(gòu)體類型
應(yīng)用自定義數(shù)據(jù)類型
在起始數(shù)據(jù)處右鍵->Structure->自定義的數(shù)據(jù)類型
ARM匯編中的標(biāo)志寄存器與條件代碼
跳轉(zhuǎn)指令b指令:跳轉(zhuǎn)
bl指令:跳轉(zhuǎn)且保存返回地址
blx/bx指令:帶x,可以切換指令集
分支指令例子:
beq=b+eq(equal)=b指令+條件助記符(參考下面的cond)
ben
條件執(zhí)行
ARM中大部分的指令都支持帶條件執(zhí)行。
cond:前四位保存條件碼
比較指令的大用處
Compare 指令:cmp r0,#1
完成操作:減法運(yùn)算(不保存結(jié)果)
根據(jù)結(jié)果更新標(biāo)志位
標(biāo)志寄存器
APSR 寄存器
標(biāo)志寄存器是條件執(zhí)行的基礎(chǔ)。
N、Z、C、V用于條件標(biāo)志位
N - 負(fù)數(shù)標(biāo)志位
Z - 零標(biāo)志位
C - 進(jìn)位標(biāo)志位
V - 溢出標(biāo)志位
比如,若減法運(yùn)算之后為負(fù)數(shù),則N為1;為0,則Z=1;
一些會(huì)修改標(biāo)志位的指令
1. 指令后綴帶S的指令,例如(MOVS)
2. TST(and)、TEQ(or)、CMN(add)、CMP(sub)
例如MOVS之后的到的值為0,那么Z就被置位(為1)
完整一點(diǎn)的例子
這里if有兩種可能,一種是a<=10,一種是a>10;
在匯編中先cmp a,#10
然后選擇if括號(hào)內(nèi)相反的選項(xiàng) bgt next1 (大于則跳轉(zhuǎn)出去)
然后在這中間填入if代碼塊中的內(nèi)容
實(shí)例分析
打開程序
導(dǎo)出表
libcinit的第三個(gè)參數(shù)(R2)是main函數(shù)的地址
跳入main函數(shù)之后發(fā)現(xiàn)IDA未能把ARM指令集識(shí)別正確。需要手動(dòng)(ALT+G)
隨便輸入一個(gè)不等于0x0的數(shù)
全部改好之后就識(shí)別出來了
程序源碼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30int ()
{
int a = 0,b = 0;
printf("This is condition statements re test!nPlease input two number:");
scanf("%d%d",&a,&b);
if(a + b == 10)
{
printf("[if]a+b=10b");
}
if(a > b){
printf("[if-else-1]a > bn");
}else if(a == b){
printf("[if-else-if] a==bn");
}else{
printf("[if-else] a
}
if(a > 10)
{
if(a <= 20)
{
printf("[nest if]n");
}
printf("a > 10n");
}
return 0;
}
自己調(diào)試一下
生成thumb代碼
BL的下一條指令的地址被保存在LR寄存器中
調(diào)用gcc的內(nèi)建函數(shù),R0作為參數(shù)
R1=LR=57C(待調(diào)試) R1=R1+2=57E(待調(diào)試) 地址做移位是為了對(duì)齊(如這里的R1),而數(shù)移位是為了做乘除法(如這里的R0)
LSRS: R1=R1右移兩位
LSLS:R0=R0左移兩位=R0*4
LSLS:R1=R1左移兩位 //先右移再左移,清除R1原來的最低位,用于對(duì)齊,得到0x580(待調(diào)試)
LDR:R0=[R1+R0] =[580+原來的R04] //假設(shè)原來的R0=1,則R0=[580+原來R04]=[580+4]=[0x584]=loc_59C-0x580
ADDS: R0=R0+R1=loc_59C
MOV: LR=loc_59C
POP: 恢復(fù)寄存器R0,R1
MOV: PC=loc_59C;函數(shù)結(jié)束,跳轉(zhuǎn)到case:選中的代碼塊
這些不是代碼,是長為4字節(jié)的數(shù)據(jù)項(xiàng),每一項(xiàng)都是偏移值,這個(gè)偏移值+0x580就能找到真正的代碼
生成ARM代碼
ADDLS:PC=PC+(R3*4)
PC的PC寄存器指向的不是下條指令,是下下條指令(也就是當(dāng)前指令地址+8)CEMU測(cè)試bl funl //把LR設(shè)置為BL指令的下一條地址fun1:mov r0,pcmov r1,lr
差了8個(gè)字節(jié)
關(guān)于ARM中的寄存器PC
從圖中可以看出,一條匯編指令的運(yùn)行有三個(gè)步驟,取指、譯碼、執(zhí)行,當(dāng)?shù)谝粭l匯編指令取指完成后,緊接著就是第二條指令的取指,然后第三條…如此嵌套
其實(shí)很容易看出,第一條指令:
add r0, r1,$5
取指完成后,PC就指向了第二條指令,此時(shí)PC=PC+4
當(dāng)?shù)谝粭l指令譯碼完成以后,此時(shí)PC=PC+8
所以第一條指令開始執(zhí)行時(shí),PC值已經(jīng)加了8
所以必須記住這個(gè)前提,在arm中,每次該指令執(zhí)行時(shí),其實(shí)這時(shí)的PC值是PC=PC+8
而且這個(gè)前提也同樣適合多級(jí)流水線,原因就不解釋了
總結(jié)
以上是生活随笔為你收集整理的android arm 寄存器,ARM汇编的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上百台linux的服务器互信,批量自动建
- 下一篇: 计算机键盘正确指法操作方法,“认识键盘与