日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android arm 寄存器,ARM汇编

發布時間:2024/9/27 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android arm 寄存器,ARM汇编 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

8種機械鍵盤軸體對比

本人程序員,要買一個寫代碼的鍵盤,請問紅軸和茶軸怎么選?

Android Native 進程啟動流程

ARM傳參,R0-R3傳遞前四個參數

1. Thumb 指令集特點Thumb 指令集指令長度:16或32,16為為主

Thumb-16 大部分只能訪問前8個寄存器 R0-R7(少數可以訪問R8-R15)

Thumb-32 可以訪問所有的ARM core 寄存器 R0-R15

更小、更加靈活

2. ARM指令集特點指令長度32位,4字節對齊

功能更加完善

對比ThumbARM2字節對齊4字節對齊

占用空間少、密度高占用空間較多

功能不齊全功能齊全

ARM和Thumb指令集各有自己的優點,取長補短往往會得到最好的性能

3. Opcod 中判斷指令集Opcode[15:13]== 111 && Opcode[12:11]!= 00 滿足則為32bit 的ARM

bl #0x80000fbc

0xed 0xff 0xff 0xeb

4. IDA 中識別與切換指令集Edit->segments->change segment register value(快捷鍵ALT+G)

請看操作。

這有一段指令,判斷出目前是thumb指令集的

按下ALT+G,把0x1改成0x0,就是指定為ARM指令集

然后按下P鍵定義函數,函數參數就都分析出來了(

5. ARM切換指令集原理處理器無論在ARM還是Thumb狀態下都可以通過BX/BLX/LDR/LDM切換不同的指令集。

狀態切換是由寄存器Rn的最低位來指定的,如果操作數寄存器的狀態位Bit0=0,則進入ARM狀態,如果Bit0=1,則進入Thumb狀態。

ARM 中對于字節、字、雙字的定義

注意和intel匯編的區別,一個word(字)這里是4個字節

但是注意一下,在IDA中依然延續著老的傳統,一個DCW(word)代表兩個字節DCB 定義1字節數據

DCW 定義2字節數據

DCD 定義4字節數據

在IDA中,在上面這些數據定義上按下D鍵可以切換定義的類型

Array 定義數組,右鍵或*號鍵

數組最常見的就在數組,

IDA中的自定義數據類型

Structures 窗口中可以創建一個自定義結構體。按下I或者Ins鍵即可創建。

創建了一個名為test的結構體

因為沒有定義字段,所以現在都還是空的,結構體長度為0(相當于空結構體,沒有任何內容)

所以去定義字段。

為自定義數據類型添加字段

創建完結構體后,長這樣:

在ends處按下D鍵就可以定義一個字段了,在字段上按D可以改變長度1/2/4

其他按鍵:

這樣就可以給一個變量轉成自己的結構體類型

應用自定義數據類型

在起始數據處右鍵->Structure->自定義的數據類型

ARM匯編中的標志寄存器與條件代碼

跳轉指令b指令:跳轉

bl指令:跳轉且保存返回地址

blx/bx指令:帶x,可以切換指令集

分支指令例子:

beq=b+eq(equal)=b指令+條件助記符(參考下面的cond)

ben

條件執行

ARM中大部分的指令都支持帶條件執行。

cond:前四位保存條件碼

比較指令的大用處

Compare 指令:cmp r0,#1

完成操作:減法運算(不保存結果)

根據結果更新標志位

標志寄存器

APSR 寄存器

標志寄存器是條件執行的基礎。

N、Z、C、V用于條件標志位

N - 負數標志位

Z - 零標志位

C - 進位標志位

V - 溢出標志位

比如,若減法運算之后為負數,則N為1;為0,則Z=1;

一些會修改標志位的指令

1. 指令后綴帶S的指令,例如(MOVS)

2. TST(and)、TEQ(or)、CMN(add)、CMP(sub)

例如MOVS之后的到的值為0,那么Z就被置位(為1)

完整一點的例子

這里if有兩種可能,一種是a<=10,一種是a>10;

在匯編中先cmp a,#10

然后選擇if括號內相反的選項 bgt next1 (大于則跳轉出去)

然后在這中間填入if代碼塊中的內容

實例分析

打開程序

導出表

libcinit的第三個參數(R2)是main函數的地址

跳入main函數之后發現IDA未能把ARM指令集識別正確。需要手動(ALT+G)

隨便輸入一個不等于0x0的數

全部改好之后就識別出來了

程序源碼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;

}

自己調試一下

生成thumb代碼

BL的下一條指令的地址被保存在LR寄存器中

調用gcc的內建函數,R0作為參數

R1=LR=57C(待調試) R1=R1+2=57E(待調試) 地址做移位是為了對齊(如這里的R1),而數移位是為了做乘除法(如這里的R0)

LSRS: R1=R1右移兩位

LSLS:R0=R0左移兩位=R0*4

LSLS:R1=R1左移兩位 //先右移再左移,清除R1原來的最低位,用于對齊,得到0x580(待調試)

LDR:R0=[R1+R0] =[580+原來的R04] //假設原來的R0=1,則R0=[580+原來R04]=[580+4]=[0x584]=loc_59C-0x580

ADDS: R0=R0+R1=loc_59C

MOV: LR=loc_59C

POP: 恢復寄存器R0,R1

MOV: PC=loc_59C;函數結束,跳轉到case:選中的代碼塊

這些不是代碼,是長為4字節的數據項,每一項都是偏移值,這個偏移值+0x580就能找到真正的代碼

生成ARM代碼

ADDLS:PC=PC+(R3*4)

PC的PC寄存器指向的不是下條指令,是下下條指令(也就是當前指令地址+8)CEMU測試bl funl //把LR設置為BL指令的下一條地址fun1:mov r0,pcmov r1,lr

差了8個字節

關于ARM中的寄存器PC

從圖中可以看出,一條匯編指令的運行有三個步驟,取指、譯碼、執行,當第一條匯編指令取指完成后,緊接著就是第二條指令的取指,然后第三條…如此嵌套

其實很容易看出,第一條指令:

add r0, r1,$5

取指完成后,PC就指向了第二條指令,此時PC=PC+4

當第一條指令譯碼完成以后,此時PC=PC+8

所以第一條指令開始執行時,PC值已經加了8

所以必須記住這個前提,在arm中,每次該指令執行時,其實這時的PC值是PC=PC+8

而且這個前提也同樣適合多級流水線,原因就不解釋了

總結

以上是生活随笔為你收集整理的android arm 寄存器,ARM汇编的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。