新手必須看的arm彙編基礎

2021-06-27 22:21:22 字數 3856 閱讀 8493

先看個例子:

void test2(int a,int b,int c)

gcc反彙編:

00000064 :

mov     ip, sp                  //ip=sp;儲存

sp新手

s***b   sp!,    //先對sp減

4,再對fp,

ip,lr,

pc壓棧。

---------1

sub     fp, ip, #4      ; 0x4   //fp=ip-4;此時

fp指向棧裡面的「fp」

sub     sp, sp, #24     ; 0x18 //分配空間

str     r0, [fp, #-28]          //

str     r1, [fp, #-32]          //

str     r2, [fp, #-36]          //引數壓棧

ldr     r3, [fp, #-28]          //

str     r3, [fp, #-24]          //

ldr     r3, [fp, #-32]          //

str     r3, [fp, #-20]          //

ldr     r3, [fp, #-36]          //

str     r3, [fp, #-16]          //

sub     sp, fp, #12     ; 0xc   //sp=fp-12;此時

sp指向棧裡面的

lrldmia   sp,         //彈棧

pc=lr

,sp=ip

,fp=fp

。然後位址加

4---------1

彙編基礎:

s***b   sp!,  //sp=sp-4,sp=pc;先壓

pc//sp=sp-4,sp=lr;再壓

lr//sp=sp-4,sp=ip;再壓

ip//sp=sp-4,sp=fp;再壓

fpldmia   sp,       //和

s***b

成對使用,

//fp=sp,sp=sp+4;先彈

fp//sp=sp,sp=sp+4;先彈

sp,此處的彈出不會影響

sp,因為

ldmia

是乙個機器週期執行完的。

//pc=sp,sp=sp+4;先彈

pcldrh          r0, [r13, #0xc] //載入無符號半字資料,即低16位

ldrb          r0, [r13, #0x4] //載入一位元組資料,即低8位。

注意:r11=fp;r12=ip;r13=sp

;r14=lr

;r15=pc

;r0,r1,r2

用於傳遞引數和存放函式返回值。

注意;低位址的暫存器被壓入低位址記憶體中,也就是說如果向下增長,高位址暫存器先壓,向上增長測試低位址先壓。

注意:根據「arm-thumb 

過程呼叫標準」:

1, r0-r3 

用作傳入函式引數,傳出函式返回值。在子程式呼叫之間,可以將 

r0-r3 

用於任何用途。被呼叫函式在返回之前不必恢復 

r0-r3

。---

如果呼叫函式需要再次使用 

r0-r3 

的內容,則它必須保留這些內容。

2, r4-r11 

被用來存放函式的區域性變數。如果被呼叫函式使用了這些暫存器,它在返回之前必須恢復這些暫存器的值。

3, r12 

是內部呼叫暫時暫存器 

ip。它在過程鏈結膠合**(例如,互動操作膠合**)中用於此角色。在過程呼叫之間,可以將它用於任何用途。被呼叫函式在返回之前不必恢復 

r12。

4,暫存器 

r13 

是棧指標 

sp。它不能用於任何其它用途。

sp 中存放的值在退出被呼叫函式時必須與進入時的值相同。

5,暫存器 

r14 

是鏈結暫存器 

lr。如果您儲存了返回位址,則可以在呼叫之間將 

r14 

用於其它用途,程式返回時要恢復

6,暫存器 

r15 

是程式計數器 

pc。它不能用於任何其它用途。

7,在中斷程式中,所有的暫存器都必須保護,編譯器會自動保護r4~

r11,所以一般你自己只要在程式的開頭

sub lr,lr,#4

stmfd sp!,;保護r0~

r3,r12,lr

就可以了,除非你用彙編人為的去改變

r4~r11

的值。(具體去看

ucos os_cpu_a.s

中的irq

中斷的**)

補充:暫存器名字

reg # apcs 意義

r0 a1 工作暫存器

r1 a2 "

r2 a3 "

r3 a4 "

r4 v1 必須保護

r5 v2 "

r6 v3 "

r7 v4 "

r8 v5 "

r9 v6 "

r10 sl 棧限制

r11 fp 楨指標

r12 ip 

r13 sp 棧指標

r14 lr 連線暫存器

r15 pc 程式計數器

回溯結構

暫存器 fp (

楨指標)

應當是零或者是指向棧回溯結構的列表中的最後乙個結構,提供了一種追溯程式的方式,來反向跟蹤呼叫的函式。

回溯結構是:

位址高階

儲存**指標

[fp]         fp 

指向這裡

返回 lr 值

[fp, #-4]

返回 sp 值

[fp, #-8]

返回 fp 值

[fp, #-12] 

指向下乙個結構

[儲存的 

sl]

[儲存的 

v6]

[儲存的 

v5]

[儲存的 

v4]

[儲存的 

v3]

[儲存的 

v2]

[儲存的 

v1]

[儲存的 

a4]

[儲存的 

a3]

[儲存的 

a2]

[儲存的 

a1]

[儲存的 

f7]                          

三個字

[儲存的 

f6]                          

三個字

[儲存的 

f5]                          

三個字

[儲存的 

f4]                          

三個字

pc 總是包含下乙個要被執行的指令的位置。

lr (總是

)包含著退出時要裝載到 

pc 中的值。在 

26-bit 

位**中它還包含著 

psr。

sp 指向當前的棧塊

(chunk)

限制,或它的上面。這是用於複製臨時資料、暫存器和類似的東西到其中的地方。在 

risc os 

下,你有可選擇的至少 

256 

位元組來擴充套件它。

fp 要麼是零,要麼指向回溯結構的最當前的部分。 

ARM彙編基礎

簡介 在armv6中,simd指令使用位 19 16 作為結果的單個位元組或半字的大於或等於 ge 標誌。您可以使用這些標誌來控制以後的sel指令,有關詳細資訊,請參閱第a4 127頁的sel 設定規則有以下三種 指令為半字操作 根據上半字計算的結果,將ge 3 2 設定或清除 根據下半字計算的結果...

ARM彙編程式設計基礎之四 ARM彙編偽操作

掌握了基本的arm彙編指令後,要寫出簡單的arm匯程式設計序,還必須要掌握基本的arm彙編偽操作 directive 現在我們來看乙個簡單的匯程式設計序,該程式呼叫子程式完成了加法操作。1 檔名 test.s 2 功能 實現兩個暫存器相加 3 area example,code,readonly 宣...

ARM彙編程式設計基礎之四 ARM彙編偽操作

掌握了基本的arm彙編指令後,要寫出簡單的arm匯程式設計序,還必須要掌握基本的arm彙編偽操作 directive 現在我們來看乙個簡單的匯程式設計序,該程式呼叫子程式完成了加法操作。1 檔名 test.s 2 功能 實現兩個暫存器相加 3 area example,code,readonly 宣...