[arm-匯編stmdb卵贱、ldmia滥沫、stmfd、ldmfd]

STMFD

  • ST - store
  • M - Multiple
  • F - FULL
  • D - Descending

LDMFD

  • LD - Load
  • M - Multiple
  • F - FULL
  • D - Descending

棧指針通臣柙蓿可以指向不同的位置佣谐。棧指針指向棧頂元素(即最后一個入棧的數(shù)據(jù)元素)時稱為FULL棧肚吏;棧指針指向與棧頂元素相鄰的一個可用書局單元時稱為EMPTY棧方妖。

數(shù)據(jù)棧的增長方向也可以不同。當數(shù)據(jù)棧向內(nèi)存地址減小的方向增長時罚攀,稱為Descending棧党觅;當數(shù)據(jù)棧向內(nèi)存地址增加的方向增長時,稱為 Ascending棧

綜合上面兩點斋泄,可以存在以下四種數(shù)據(jù)棧:

  • FD - Full Descending
  • ED - Empty Descending
  • FA - Full Ascending
  • EA - Empty Ascending

因此實際上存在下面這些批量load/save指令:
LDMFA, LDMFD, LDMEA, LDMED
STMED, STMEA, STMFD, STMFA

給定數(shù)據(jù)棧對應著的特定批量load/save指令杯瞻,也決定了地址變化方式:
比如FD棧,對應的批量傳送指令是LDMFD/STMFD炫掐,對應的地址變化方式是:

  • IA(事后遞增方式)
  • DB(事先遞減方式)
STMFD SP!, {R0~R7, LR}
start_address = sp - 9 * 4          //先壓棧魁莉,然后增長sp
end_address = sp - 4

把寄存器r0~r7和LR共9個寄存器,存儲到start_address開始, 到end_address結(jié)束的棧中旗唁,并且修改SP的值(SP變衅枧ā),相當于壓棧检疫。

LDMFD SP!, {R0~R7, LR}
start_address = SP
end_address = SP + 9 * 4

把堆棧從start_address開始讶请,到end_address內(nèi)的值恢復到寄存器R0, R1... R7和LR中,并修改SP的值(SP變大)屎媳,相當于出棧夺溢。

首先一句話說一下stmdb和ldmia指令的作用:
stmdb和ldmia指令一般配對使用,stmdb用于將寄存器壓棧烛谊,ldmia用于將寄存器彈出棧风响,作用是保存使用到的寄存器。

ARM指令的多數(shù)據(jù)傳輸(STM晒来、LDM)中钞诡,提到:多寄存器的Load和Store指令分為2組:一組用于數(shù)據(jù)的存儲與讀取,對應于IA湃崩、IB荧降、DA、DB攒读,一組用于堆棧操作朵诫,對應于FD、ED薄扁、FA剪返、EA,兩組中對應的指令含義相同邓梅。
即:

STMIB(地址先增而后完成操作)脱盲、STMFA(滿遞增堆棧);
STMIA(完成操作而后地址遞增)日缨、STMEA(空遞增堆棧)钱反;
STMDB(地址先減而后完成操作)、STMFD(滿遞減堆棧)匣距;
STMDA(完成操作而后地址遞減)面哥、STMED(空遞減堆棧)。
上述各組2個指令含義相同只是適用場合不同毅待,同理有:
LDMIB尚卫、LDMED;

LDMIA尸红、LDMFD吱涉;
LDMDB刹泄、LDMEA;
LDMDA怎爵、LDMFA循签。

IA模式表示:每次傳送后地址+4;(After Increase)DB模式表示:每次傳送前地址-4疙咸;(Before Decrease)多寄存器加載/存儲指令共有8種模式(4個用與數(shù)據(jù)塊的傳輸县匠,4個用于棧操作)

舉例一:

指令:stmdb sp!,{r0-r12,lr}  

含義:sp = sp - 4,先壓lr撒轮,sp = lr(即將lr中的內(nèi)容放入sp所指的內(nèi)存地址)乞旦。sp = sp - 4,再壓r12题山,sp = r12兰粉。sp = sp - 4,再壓r11顶瞳,sp = r11......sp = sp - 4玖姑,最后壓r0,sp = r0慨菱。

如果想要將r0-r12和lr彈出焰络,可以用ldmia指令:

指令:ldmia sp!,{r0-r12,lr}  

舉例二:


STMIA, 比如當前r0指向的內(nèi)存地址是 0x1000符喝,STMIA R0!,{R1-R7} 就是 首先把r1存入 0x1000,然后r2存入0x1004闪彼,然后r3存入0x1008,如果是32位的處理器就是每次加4個字節(jié)协饲,以此類推把 r1-r7按照遞增的地址存入畏腕,這個r0!就是從r0的地址開始存的意思。STMDB則是地址從r0開始減少茉稠,依次存儲描馅。

第二部分代碼說明:

先看個例子:

void test2(int a,int b,int c)
{ 
int k=a,j=b,m=c;

}
GCC反匯編:
00000064 <test2>:
mov      ip, sp                   //IP=SP;保存SP
stmdb    sp!, {fp, ip, lr, pc}    //先對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]           //參數(shù)壓棧
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, {fp, sp, pc}         //彈棧pc=lr各拷,sp=ip,fp=fp闷营。然后地址加4---------1

匯編基礎:

stmdb    sp!, {fp, ip, lr, pc} 
//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, {fp, sp, pc}       
//和stmdb成對使用烤黍,
//fp=sp,sp=sp+4;先彈fp
//sp=sp,sp=sp+4;先彈sp知市,此處的彈出不會影響sp,因為ldmia是一個機器周期執(zhí)行完的速蕊。
//pc=sp,sp=sp+4;先彈pc
LDRH           R0, [R13, #0xC] //加載無符號半字數(shù)據(jù)嫂丙,即低16位
LDRB           R0, [R13, #0x4] //加載一字節(jié)數(shù)據(jù),即低8位规哲。

注意1:R11=fp;R12=ip;R13=SP跟啤;R14=LR;R15=PC唉锌;R0,R1,R2用于傳遞參數(shù)和存放函數(shù)返回值隅肥。
**注意2: ** 低地址的寄存器被壓入低地址內(nèi)存中,也就是說如果向下增長袄简,高地址寄存器先壓腥放,向上增長測試低地址先壓。
注意3:根據(jù)“ARM-thumb 過程調(diào)用標準”:

  1. r0-r3 用作傳入函數(shù)參數(shù)绿语,傳出函數(shù)返回值秃症。在子程序調(diào)用之間,可以將 r0-r3 用于任何用途吕粹。被調(diào)用函數(shù)在返回之前不必恢復 r0-r3种柑。---如果調(diào)用函數(shù)需要再次使用 r0-r3 的內(nèi)容,則它必須保留這些內(nèi)容匹耕。
  2. r4-r11 被用來存放函數(shù)的局部變量莹规。如果被調(diào)用函數(shù)使用了這些寄存器,它在返回之前必須恢復這些寄存器的值泌神。
  3. r12 是內(nèi)部調(diào)用暫時寄存器 ip良漱。它在過程鏈接膠合代碼(例如,交互操作膠合代碼)中用于此角色欢际。在過程調(diào)用之間母市,可以將它用于任何用途。被調(diào)用函數(shù)在返回之前不必恢復 r12损趋。
  4. 寄存器 r13 是棧指針 sp患久。它不能用于任何其它用途。sp 中存放的值在退出被調(diào)用函數(shù)時必須與進入時的值相同浑槽。
  5. 寄存器 r14 是鏈接寄存器 lr蒋失。如果您保存了返回地址,則可以在調(diào)用之間將 r14 用于其它用途桐玻,程序返回時要恢復
  6. 寄存器 r15 是程序計數(shù)器 PC篙挽。它不能用于任何其它用途。
  7. 在中斷程序中镊靴,所有的寄存器都必須保護铣卡,編譯器會自動保護R4~R11链韭,所以一般你自己只要在程序的開頭

sub lr,lr,#4
stmfd sp!,{r0-r3,r12,lr};
// 保護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 程序計數(shù)器

回溯結(jié)構(gòu)
寄存器 fp (楨指針)應當是零或者是指向棽醭穑回溯結(jié)構(gòu)的列表中的最后一個結(jié)構(gòu)旋讹,提供了一種追溯程序的方式,來反向跟蹤調(diào)用的函數(shù)轿衔。

回溯結(jié)構(gòu)是:
地址高端

保存代碼指針         [fp]          fp 指向這里

返回 lr 值           [fp, #-4]

返回 sp 值           [fp, #-8]

返回 fp 值           [fp, #-12]  指向下一個結(jié)構(gòu)

[保存的 sl]

[保存的 v6]

[保存的 v5]

[保存的 v4]

[保存的 v3]

[保存的 v2]

[保存的 v1]

[保存的 a4]

[保存的 a3]

[保存的 a2]

[保存的 a1]

[保存的 f7]                           三個字

[保存的 f6]                           三個字

[保存的 f5]                           三個字

[保存的 f4]                           三個字

pc 總是包含下一個要被執(zhí)行的指令的位置骗村。
lr (總是)包含著退出時要裝載到 pc 中的值。在 26-bit 位代碼中它還包含著 PSR呀枢。
sp 指向當前的棧塊(chunk)限制胚股,或它的上面。這是用于復制臨時數(shù)據(jù)裙秋、寄存器和類似的東西到其中的地方琅拌。在 RISC OS 下,你有可選擇的至少 256 字節(jié)來擴展它摘刑。
fp 要么是零进宝,要么指向回溯結(jié)構(gòu)的最當前的部分。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末枷恕,一起剝皮案震驚了整個濱河市党晋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徐块,老刑警劉巖未玻,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異胡控,居然都是意外死亡扳剿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門昼激,熙熙樓的掌柜王于貴愁眉苦臉地迎上來庇绽,“玉大人,你說我怎么就攤上這事橙困∏撇簦” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵凡傅,是天一觀的道長辟狈。 經(jīng)常有香客問我,道長像捶,這世上最難降的妖魔是什么上陕? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮拓春,結(jié)果婚禮上释簿,老公的妹妹穿的比我還像新娘。我一直安慰自己硼莽,他們只是感情好庶溶,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著懂鸵,像睡著了一般偏螺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匆光,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天套像,我揣著相機與錄音,去河邊找鬼终息。 笑死夺巩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的周崭。 我是一名探鬼主播柳譬,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼续镇!你這毒婦竟也來了美澳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤摸航,失蹤者是張志新(化名)和其女友劉穎制跟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酱虎,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡凫岖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逢净。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哥放。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爹土,靈堂內(nèi)的尸體忽然破棺而出甥雕,到底是詐尸還是另有隱情,我是刑警寧澤胀茵,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布社露,位于F島的核電站,受9級特大地震影響琼娘,放射性物質(zhì)發(fā)生泄漏峭弟。R本人自食惡果不足惜附鸽,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瞒瘸。 院中可真熱鬧坷备,春花似錦、人聲如沸情臭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俯在。三九已至竟秫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跷乐,已是汗流浹背肥败。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留愕提,地道東北人拙吉。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像揪荣,于是被迫代替她去往敵國和親筷黔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 原文地址 一仗颈、Hopper中的ARM指令ARM處理器就不多說了佛舱,ARM處理器因為低功耗等原因,所以大部分移動設備上...
    顏值不夠才華來湊閱讀 1,141評論 0 4
  • 前言 本文翻譯自iOS Assembly Tutorial: Understanding ARM 翻譯的不對的地...
    桃紅宿雨閱讀 18,060評論 7 198
  • 今天挨决,讓我們一起走進C型(思考型)人的世界吧请祖。 在日常生活中,和C型(思考型)人溝通起來有哪些痛點呢脖祈? 他們吹毛求...
    小原ing閱讀 6,215評論 0 0
  • Java 中的異常處理機制:Java中的異常有兩大類:Error:系統(tǒng)錯誤肆捕,往往是 由軟件運行的硬件換件遭破壞所導...
    itachi閱讀 714評論 0 2