arm彙編基礎**)
先看個例子:
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指向棧裡面的lr
ldmia 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;再壓fp
ldmia sp, //和s***b成對使用,
//fp=sp,sp=sp+4;先彈fp
//sp=sp,sp=sp+4;先彈sp,此處的彈出不會影響sp,因為ldmia是乙個機器週期執行完的。
//pc=sp,sp=sp+4;先彈pc
ldrh 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 中存放的值在退出被呼叫函式時必須與進入時的值相同。
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 要麼是零,要麼指向回溯結構的最當前的部分。
組合語言中的常數
1,數值常數 二進位制數 10110100b 八進位制數146q,5430 十進位制數146d,543 十六進製制數 1a2fh,0ff00h 實數12.48e 2,1a3c0000r 彙編時,則有匯程式設計序將所有的數值常數都轉換成二進位制標示的目標 凡是以字母a f開頭的十六進製制數,唏噓在前面...
組合語言中ASSUME簡介
size large url 組合語言中的assume偽指令 directive assume偽指令通知匯程式設計序為 段 資料段 附加段以及堆疊段選擇什麼名字。沒有assume偽指令時,匯程式設計序假設不分段,並自動把段超越字首用於所有定址儲存器資料的偽指令。assume語句只能用於完整的段定義。...
組合語言中xor指令 計算機組合語言
組合語言 雖然用機器語言編寫程式有很高的要求和許多不便,但編寫出來的程式執 行效率高,cpu嚴格按照程式設計師的要求去做,沒有多餘的額外操作。所以,在保留 程式執行效率高 的前提下,人們就開始著手研究一種能大大改善 程式可讀性的程式設計方法。為了改善機器指令的可讀性,選用了一些能反映機器指令功能的單...