匯編三

匯編常用指令

  • sub 拉伸椝瘢空間
sub sp, sp, #0x20
sp 是棧頂铺然,由于棧是由高地址到低地址裕偿,
一次性拉伸32個(gè)字節(jié)就需要將棧頂?shù)刂窚p去0x20(棧是16字節(jié)對(duì)齊的)
  • str (store register) 將數(shù)據(jù)從寄存器中讀出來(lái),存到內(nèi)存中.
  • stp 是str的延伸赡鲜,可以同時(shí)存儲(chǔ)兩個(gè)
str x0,[sp,#0x10]
將x0的值存在以sp+0x10為地址的存儲(chǔ)器中(棧空間內(nèi)存)
stp x29,x30,[sp,#0x20]
sp往上加32(20 = 2 * 16)個(gè)字節(jié),存放x29 和 x30
  • ldr(load register)讀取指令
    將數(shù)據(jù)從內(nèi)存中讀取出來(lái), 存到寄存器中氮帐,LDR:通常都是作加載指令的隘截,但是它也可以作偽指令

  • ldp是ldr的衍生, 可以同時(shí)讀兩個(gè)寄存器

 LDR r0,[r1]        //將R1中的值存到r0中
 LDR r1,[r2,#16]     //將(r2+16)地址中的內(nèi)容存到r1中
 LDR r1,[r2],#4      //將r2地址中的內(nèi)容存到r1中,同時(shí)r2=r2+4

sub sp, sp, #0x20 ; 拉伸椩祝空間32(20 = 2*16)個(gè)字節(jié)
stp x0 , x1, [sp, #0x10] ; sp往上加16(10 = 1 * 16)個(gè)字節(jié),存放x0 和 x1
ldp x1 , x0, [sp, #0x10] ; 將sp偏移16個(gè)字節(jié)的值取出來(lái),放入x1 和 x0
  • adrp 通過(guò)基地址 + 偏移 獲得一個(gè)字符串(全局變量)
原理 adrp操作步驟adrp x0, 1

1. 將1的值,左移12位 1 0000 0000 0000 == 0x1000

2.將PC寄存器的低12位清零 0x1045228b0  ==> 0x104522000

3.將將1 和 2 的結(jié)果相加  給 X0 寄存器!! ==>0x104523000

4.add x1,x0,#0xfd8 即將第三布得出的結(jié)果加上0xfd8 ==>0x104523fd8 就可以得出全局變量或者常量所在的地址

注:地址為pc寄存器左邊的地址,adrp是找出要獲取參數(shù)的地址范圍婶芭,然后下個(gè)pc寄存器執(zhí)行的代碼會(huì)定位到準(zhǔn)確的物理地址东臀。

  • cbz :【cbz 寄存器,地址 】指令的意思是 如果寄存器的值==0犀农,則跳轉(zhuǎn)到地址惰赋,如果不等于0,則繼續(xù)執(zhí)行代碼
  • subs : subs其實(shí)就是sub指令呵哨,但是這個(gè)指令操作結(jié)束后赁濒,會(huì)影響到標(biāo)志寄存器

cmp(Compare)比較指令

???CMP 把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行比較。但不存儲(chǔ)結(jié)果孟害,只是正確的更改標(biāo)志拒炎。
???一般CMP做完判斷后會(huì)進(jìn)行跳轉(zhuǎn),后面通常會(huì)跟上b指令挨务!

  • bl 標(biāo)號(hào):跳轉(zhuǎn)到標(biāo)號(hào)處執(zhí)行
  • b.gt 標(biāo)號(hào):比較結(jié)果是大于(greater than)击你,執(zhí)行標(biāo)號(hào),否則不跳轉(zhuǎn)
  • b.ge 標(biāo)號(hào):比較結(jié)果是大于等于(greater than or equal to)谎柄,執(zhí)行標(biāo)號(hào)丁侄,否則不跳轉(zhuǎn)
  • b.eq 標(biāo)號(hào):比較結(jié)果是等于,執(zhí)行標(biāo)號(hào)朝巫,否則不跳轉(zhuǎn)
  • b.hi 標(biāo)號(hào):比較結(jié)果是無(wú)符號(hào)大于鸿摇,執(zhí)行標(biāo)號(hào),否則不跳轉(zhuǎn)
  • b.le 標(biāo)號(hào):判斷上面cmp的值是小于等于 執(zhí)行標(biāo)號(hào),否則直接往下走
  • b.lt 判斷上面cmp的值是 小于 執(zhí)行后面的地址中的方法 否則直接往下走
CPY 把一個(gè)寄存器的值拷貝(COPY)到另一個(gè)寄存器中
EOR 近位異或
LSL 邏輯左移(Logic Shift Left)
LSR 邏輯右移(Logic Shift Right)
MOV 寄存器加載數(shù)據(jù)竟痰,既能用于寄存器間的傳輸卢肃,也能用于加載立即數(shù)
MUL 乘法(Multiplication)
MVN 加載一個(gè)數(shù)的 NOT值(取到邏輯反的值)
NEG 取二進(jìn)制補(bǔ)碼
ORR 按位或
ROR 循環(huán)右移
SBC 帶借位的減法
SUB 減法(Subtraction)
TST 測(cè)試(Test,執(zhí)行按位與操作庐镐,并且根據(jù)結(jié)果更新Z)
REV 在一個(gè)32位寄存器中反轉(zhuǎn)(Reverse)字節(jié)序
REVH 把一個(gè)32位寄存器分成兩個(gè)(Half)16位數(shù),在每個(gè)16位數(shù)中反轉(zhuǎn)字節(jié)序
REVSH 把一個(gè)32位寄存器的低16位半字進(jìn)行字節(jié)反轉(zhuǎn)变逃,然后帶符號(hào)擴(kuò)展到32位
SXTB 帶符號(hào)(Signed)擴(kuò)展一個(gè)字節(jié)(Byte)到 32位
SXTH 帶符號(hào)(Signed)擴(kuò)展一個(gè)半字(Half)到 32位
UXTB 無(wú)符號(hào)(Unsigned)擴(kuò)展一個(gè)字節(jié)(Byte)到 32位
UXTH 無(wú)符號(hào)(Unsigned)擴(kuò)展一個(gè)半字(Half)到 32位

Switch

1必逆、假設(shè)switch語(yǔ)句的分支比較少的時(shí)候(例如3,少于4的時(shí)候沒(méi)有意義)沒(méi)有必要使用此結(jié)構(gòu)揽乱,相當(dāng)于if名眉。
2、各個(gè)分支常量的差值較大的時(shí)候凰棉,編譯器會(huì)在效率還是內(nèi)存進(jìn)行取舍损拢,這個(gè)時(shí)候編譯器還是會(huì)編譯成類似于if,else的結(jié)構(gòu)撒犀。
3福压、在分支比較多的時(shí)候:在編譯的時(shí)候會(huì)生成一個(gè)表(跳轉(zhuǎn)表每個(gè)地址四個(gè)字節(jié))掏秩。

void __switch_1__(){
    int value = 5;
    switch (value) {
        case 0:
            printf("1");
            break;
        case 1:
            printf("2");
            break;
        case 2:
            printf("3");
            break;
        default:
            printf("else");
            break;
    }
}

匯編代碼如下:

01-匯編-IF-SWITCH`__switch_1__:
    0x100c96644 <+0>:   sub    sp, sp, #0x30             ; =0x30 
    0x100c96648 <+4>:   stp    x29, x30, [sp, #0x20]
    0x100c9664c <+8>:   add    x29, sp, #0x20            ; =0x20 
->  0x100c96650 <+12>:  mov    w8, #0x5                  ; w8 = 5
    0x100c96654 <+16>:  stur   w8, [x29, #-0x4]
    0x100c96658 <+20>:  ldur   w8, [x29, #-0x4]          ; value = w8
    0x100c9665c <+24>:  mov    x9, x8
    0x100c96660 <+28>:  stur   w9, [x29, #-0x8]
    0x100c96664 <+32>:  cbz    w8, 0x100c96694           ; cbz 指令的意思是 如果w8==0,則跳轉(zhuǎn)到 0x100c96694荆姆,如果不等于0蒙幻,則繼續(xù)執(zhí)行代碼
    0x100c96668 <+36>:  b      0x100c9666c               ; <+40> at main.m:26
    0x100c9666c <+40>:  ldur   w8, [x29, #-0x8]
    0x100c96670 <+44>:  subs   w9, w8, #0x1              ; w9=w8-1
    0x100c96674 <+48>:  stur   w9, [x29, #-0xc]
    0x100c96678 <+52>:  b.eq   0x100c966a8               ; 如果w9==0,則跳轉(zhuǎn)到 0x100c966a8
    0x100c9667c <+56>:  b      0x100c96680               ; <+60> at main.m:26
    0x100c96680 <+60>:  ldur   w8, [x29, #-0x8]
    0x100c96684 <+64>:  subs   w9, w8, #0x2              ; w9=w8-2
    0x100c96688 <+68>:  str    w9, [sp, #0x10]
    0x100c9668c <+72>:  b.eq   0x100c966bc               ; 如果w9==0,則跳轉(zhuǎn)到  0x100c966bc
    0x100c96690 <+76>:  b      0x100c966d0               ; 如果都不滿足即default,則跳轉(zhuǎn)到 0x100c966d0
    0x100c96694 <+80>:  adrp   x0, 1
    0x100c96698 <+84>:  add    x0, x0, #0xf29            ; =0xf29 
    0x100c9669c <+88>:  bl     0x100c96c04               ; printf("1");
    0x100c966a0 <+92>:  str    w0, [sp, #0xc]
    0x100c966a4 <+96>:  b      0x100c966e0               ; <+156> at main.m:40
    0x100c966a8 <+100>: adrp   x0, 1
    0x100c966ac <+104>: add    x0, x0, #0xf2b            ; =0xf2b 
    0x100c966b0 <+108>: bl     0x100c96c04               ; printf("2");
    0x100c966b4 <+112>: str    w0, [sp, #0x8]
    0x100c966b8 <+116>: b      0x100c966e0               ; <+156> at main.m:40
    0x100c966bc <+120>: adrp   x0, 1
    0x100c966c0 <+124>: add    x0, x0, #0xf2d            ; =0xf2d 
    0x100c966c4 <+128>: bl     0x100c96c04               ; printf("3");
    0x100c966c8 <+132>: str    w0, [sp, #0x4]
    0x100c966cc <+136>: b      0x100c966e0               ; <+156> at main.m:40
    0x100c966d0 <+140>: adrp   x0, 1
    0x100c966d4 <+144>: add    x0, x0, #0xf24            ; =0xf24 
    0x100c966d8 <+148>: bl     0x100c96c04               ; printf("else");
    0x100c966dc <+152>: str    w0, [sp]
    0x100c966e0 <+156>: ldp    x29, x30, [sp, #0x20]
    0x100c966e4 <+160>: add    sp, sp, #0x30             ; =0x30 
    0x100c966e8 <+164>: ret 

由上可見(jiàn)胆筒,當(dāng)case為3個(gè)時(shí)邮破,匯編執(zhí)行的代碼為if else語(yǔ)句 而當(dāng)增加到4個(gè)case時(shí),匯編代碼發(fā)生了相關(guān)變化

  0x100be66f8 <+48>:  adrp   x8, 0
    0x100be66fc <+52>:  add    x8, x8, #0x790            ; x8 = 0x0000000100be6790 
    0x100be6700 <+56>:  ldur   x9, [x29, #-0x10]         ; x9 就是前面存進(jìn)來(lái)的值 也就是3
    0x100be6704 <+60>:  ldrsw  x10, [x8, x9, lsl #2]     ; 取出[0x0000000100be6790 + 03 << 2],給x10
    0x100be6708 <+64>:  add    x8, x10, x8               ; 計(jì)算出要調(diào)轉(zhuǎn)的位置
    0x100be670c <+68>:  br     x8                        ; 跳轉(zhuǎn)
  • ldrsw ldrsw x10, [x8, x9, lsl #2] lsl就是將后面的值左移 []里面的意思是將x9+ 左移后的值 賦值給x8仆救,然后通過(guò)[]取出x8寄存器所對(duì)應(yīng)的值賦值給x10

  • br (brew register) 意思與b ’地址‘ 一樣抒和,就是跳轉(zhuǎn)后面的地址

??這時(shí)分析匯編代碼就可得知:當(dāng)超過(guò)3個(gè)case并且case值里面盡可能的連續(xù)時(shí),編譯器會(huì)通過(guò)表來(lái)存儲(chǔ)相關(guān)的偏移值(由于本身編譯的時(shí)候會(huì)增加ASLR一個(gè)隨機(jī)值彤蔽,故而通過(guò)pc寄存器與偏移值之間的加減就可以直接得出相關(guān)值存在的地址)摧莽,通過(guò)br指令跳轉(zhuǎn)對(duì)應(yīng)的地址執(zhí)行下面的相關(guān)代碼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铆惑,一起剝皮案震驚了整個(gè)濱河市范嘱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌员魏,老刑警劉巖丑蛤,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異撕阎,居然都是意外死亡受裹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門虏束,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)棉饶,“玉大人,你說(shuō)我怎么就攤上這事镇匀≌赵澹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵汗侵,是天一觀的道長(zhǎng)幸缕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)晰韵,這世上最難降的妖魔是什么发乔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮雪猪,結(jié)果婚禮上栏尚,老公的妹妹穿的比我還像新娘。我一直安慰自己只恨,他們只是感情好译仗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布抬虽。 她就那樣靜靜地躺著,像睡著了一般古劲。 火紅的嫁衣襯著肌膚如雪斥赋。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天产艾,我揣著相機(jī)與錄音,去河邊找鬼滑绒。 笑死闷堡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疑故。 我是一名探鬼主播杠览,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纵势!你這毒婦竟也來(lái)了踱阿?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤钦铁,失蹤者是張志新(化名)和其女友劉穎软舌,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體牛曹,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡佛点,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黎比。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片超营。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖阅虫,靈堂內(nèi)的尸體忽然破棺而出演闭,到底是詐尸還是另有隱情,我是刑警寧澤颓帝,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布米碰,位于F島的核電站,受9級(jí)特大地震影響躲履,放射性物質(zhì)發(fā)生泄漏见间。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一工猜、第九天 我趴在偏房一處隱蔽的房頂上張望米诉。 院中可真熱鬧,春花似錦篷帅、人聲如沸史侣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)惊橱。三九已至蚪腐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間税朴,已是汗流浹背回季。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留正林,地道東北人泡一。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像觅廓,于是被迫代替她去往敵國(guó)和親鼻忠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • Switch樣式一 原C代碼如下: 匯編代碼如下: 先科普一下兩個(gè)新指令: cbz :【cbz 寄存器杈绸,地址 】...
    洪呵呵_閱讀 1,796評(píng)論 0 51
  • 函數(shù)的本質(zhì) 關(guān)于CPU的補(bǔ)充 寄存器 CPU由: 控制器, 計(jì)算器和寄存器組成. 其中寄存器的作用就是將數(shù)據(jù)進(jìn)行臨...
    請(qǐng)叫我大帥666閱讀 4,439評(píng)論 2 9
  • 1.函數(shù)的局部變量 定義一個(gè)局部變量c帖蔓,斷點(diǎn)查看匯編中c的存儲(chǔ)調(diào)用 2.函數(shù)的嵌套調(diào)用 定義2個(gè)函數(shù),funcA中...
    昵稱是亂起的閱讀 164評(píng)論 0 0
  • 一、葉子函數(shù) sp:stack point篡殷,作用是存儲(chǔ)著某塊內(nèi)存的地址钝吮。一般是通過(guò)sp來(lái)指定一塊內(nèi)存給函數(shù)使用。 ...
    Lovell_閱讀 1,916評(píng)論 1 2
  • 完整的匯編指令:#### 匯編由兩種指令組成1.匯編指令如mov板辽、add奇瘦、sub等有對(duì)應(yīng)的機(jī)器指令,可以被編譯為機(jī)...
    Flonger閱讀 435評(píng)論 0 0