一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

arm匯編

 goodwangLib 2021-10-31

(匯編)指令是CPU機(jī)器指令的助記符,經(jīng)過編譯后會(huì)得到一串10組成的機(jī)器碼,可以由CPU讀取執(zhí)行。
(匯編)偽指令本質(zhì)上不是指令(只是和指令一起寫在代碼中),它是編譯器環(huán)境提供的,目的是用來指導(dǎo)編譯過程,經(jīng)過編譯后偽指令最終不會(huì)生成機(jī)器碼。

  ARM官方的ARM匯編風(fēng)格:指令一般用大寫、Windows中IDE開發(fā)環(huán)境(如ADS、MDK等)常用。如: LDR R0, [R1]

  GNU風(fēng)格的ARM匯編:指令一般用小寫字母、linux中常用。如:ldr r0, [r1]

  ARM采用RISC架構(gòu),CPU本身不能直接讀取內(nèi)存,而需要先將內(nèi)存中內(nèi)容加載入CPU中通用寄存器中才能被CPU處理。
  ldr(load register)指令將內(nèi)存內(nèi)容加載入通用寄存器。
  str(store register)指令將寄存器內(nèi)容存入內(nèi)存空間中。
  ldr/str組合用來實(shí)現(xiàn) ARM CPU和內(nèi)存數(shù)據(jù)交換 

  寄存器尋址 mov r1, r2
  立即尋址mov r0, #0xFF00
  寄存器移位尋址mov r0, r1, lsl #3
  寄存器間接尋址ldr r1, [r2]
  基址變址尋址ldr r1, [r2, #4]
  多寄存器尋址ldmia r1!, {r2-r7, r12}
  堆棧尋址stmfd sp!, {r2-r7, lr}

  相對(duì)尋址 beq flag

  同一指令經(jīng)常附帶不同后綴,變成不同的指令。經(jīng)常使用的后綴有:
  B(byte)功能不變,操作長(zhǎng)度變?yōu)?位
  H(half word)功能不變,長(zhǎng)度變?yōu)?6位
  S(signed)功能不變,操作數(shù)變?yōu)橛蟹?hào)
  如 ldr ldrb ldrh ldrsb ldrsh
  S(S標(biāo)志)功能不變,影響CPSR標(biāo)志位
  如 mov和movsmovs r0, #0

 

 

1
2
3
4
5
6
7
  mov r0, r1 @ 相當(dāng)于C語言中的r0 = r1;
  moveq r0, r1  @ 如果eq后綴成立,則直接執(zhí)行mov r0, r1;如果eq不成立則本句代碼直接作廢,相當(dāng)于沒有
  @ 類似于C語言中 if (eq){r0 = r1;}
  條件后綴執(zhí)行注意2點(diǎn):
1、條件后綴是否成立,不是取決于本句代碼,而是取決于這句代碼之前的代碼運(yùn)行后的結(jié)果。
2、條件后綴決定了本句代碼是否被執(zhí)行,而不會(huì)影響上一句和下一句代碼是否被執(zhí)行。

  

GT greater than
LT less than

 

數(shù)據(jù)傳輸指令 mov mvn
算術(shù)指令add sub rsb adc sbc rsc
邏輯指令and orr eor bic
比較指令cmp cmn tst teq
乘法指令mvl mla umull umlal smull smlal
前導(dǎo)零計(jì)數(shù)clz

 

mrs & msr

mrs用來讀psr,msr用來寫psr
CPSR寄存器比較特殊,需要專門的指令訪問,這就是mrs和msr。 

 

  b & bl & bx

b 直接跳轉(zhuǎn)(就沒打開算返回)
bl branch and link,跳轉(zhuǎn)前把返回地址放入lr中,以便返回,以便用于函數(shù)調(diào)用
bx跳轉(zhuǎn)同時(shí)切換到ARM模式,一般用于異常處理的跳轉(zhuǎn)。

bne 指令 檢測(cè)到Z!=0 時(shí) 執(zhí)行跳轉(zhuǎn) 

beq 指令 檢測(cè)到Z   =0 時(shí) 執(zhí)行跳轉(zhuǎn)

 

ldr/str & ldm/stm & swp

單個(gè)字/半字/字節(jié)訪問 ldr/str
多字批量訪問 ldm/stm
swp r1, r2, [r0]
swp r1, r1, [r0]

合法立即數(shù)與非法立即數(shù)

ARM指令都是32位,除了指令標(biāo)記和操作標(biāo)記外,本身只能附帶很少位數(shù)的立即數(shù)。因此立即數(shù)有合法和非法之分。
合法立即數(shù):經(jīng)過任意位數(shù)的移位后非零部分可以用8位表示的即為合法立即數(shù)

 

  swi(software interrupt)

  軟中斷指令用來實(shí)現(xiàn)操作系統(tǒng)中系統(tǒng)調(diào)用

 

 

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
mov(move) mov r1, r0 @兩個(gè)寄存器之間數(shù)據(jù)傳遞
mov r1, #0xff   @ 將立即數(shù)賦值給寄存器
mvn和mov用法一樣,區(qū)別是mov是原封不動(dòng)的傳遞,而mvn是按位取反后傳遞
按位取反的含義:
譬如r1 = 0x000000ff,然后mov r0, r1 后,r0 = 0xff  但是我mvn r0, r1后,r0=0xffffff00
and 邏輯與
orr 邏輯或
eor 裸機(jī)異或
bic 位清除指令
bic r0,r1,#0x1f @ 將r1中的數(shù)的bit0到bit4清零后賦值給r0  0x1f = 0x0000001f=0x0000```11111
比較指令:
cmp cmp r0, r1 等價(jià)于 sub r2, r0, r1 (r2 = r0 - r1)
cmn cmn r0, r1 等價(jià)于 add r0, r1
tst tst r0, #0xf    @測(cè)試r0的bit0~bit3是否全為0
teq
比較指令用來比較2個(gè)寄存器中的數(shù)
注意:比較指令不用后加s后綴就可以影響cpsr中的標(biāo)志位。
cpsr和spsr的區(qū)別和聯(lián)系:cpsr是程序狀態(tài)寄存器,整個(gè)SoC中只有1個(gè);而spsr有5個(gè),分別在5種異常模式下,作用是當(dāng)從普通模式進(jìn)入異常模式時(shí),用來保存之前普通模式下的cpsr的,以在返回普通模式時(shí)恢復(fù)原來的cpsr。
合法立即數(shù): 0x000000ff   0x00ff0000 0xf000000f
非法立即數(shù): 0x000001ff

  

 

 

mcr & mrc

mrc用于讀取CP15中的寄存器
mcr用于寫入CP15中的寄存器

 

  SoC內(nèi)部另一處理核心,協(xié)助主CPU實(shí)現(xiàn)某些功能,被主CPU調(diào)用執(zhí)行一定任務(wù)。
  ARM設(shè)計(jì)上支持多達(dá)16個(gè)協(xié)處理器,但是一般SoC只實(shí)現(xiàn)其中的CP15.(cp:coprocessor)
  協(xié)處理器和MMU、cache、TLB等處理有關(guān),功能上和操作系統(tǒng)的虛擬地址映射、cache管理等有關(guān)。

 

 

mcr{<cond>} p15, <opcode_1>, <Rd>, <Crn>, <Crm>, {<opcode_2>}
opcode_1:對(duì)于cp15永遠(yuǎn)為0
Rd:ARM的普通寄存器
Crn:cp15的寄存器,合法值是c0~c15
Crm:cp15的寄存器,一般均設(shè)為c0
opcode_2:一般省略或?yàn)? 

 

舉例(來自于uboot)

mrc p15, 0, r0, c1, c0, 0
orrr0, r0, #1
mcr p15, 0, r0, c1, c0, 0

 

 

  dr/str每周期只能訪問4字節(jié)內(nèi)存,如果需要批量讀取、寫入內(nèi)存時(shí)太慢,解決方案是stm/ldm
  ldm(load register mutiple)
  stm(store register mutiple)


  舉例(uboot start.S 537行)
  stmiasp, {r0 - r12}
  將r0存入sp指向的內(nèi)存處(假設(shè)為0x30001000);然后地址+4(即指向0x30001004),將r1存入該地址;然后地址再+4(指向0x30001008),將r2存入該地址······直到r12內(nèi)容放入(0x3001030),指令完成。
  一個(gè)訪存周期同時(shí)完成13個(gè)寄存器的讀寫

 

 

8種后綴
  ia(increase after)先傳輸,再地址+4
  ib(increase before)先地址+4,再傳輸
  da(decrease after)先傳輸,再地址-4
  db(decrease before)先地址-4,再傳輸
  fd(full decrease)滿遞減堆棧
  ed(empty decrease)空遞減堆棧
  fa(·······) 滿遞增堆棧
  ea(·······)空遞增堆棧
四種棧
  空棧:棧指針指向空位,每次存入時(shí)可以直接存入然后棧指針移動(dòng)一格;而取出時(shí)需要先移動(dòng)一格才能取出
  滿棧:棧指針指向棧中最后一格數(shù)據(jù),每次存入時(shí)需要先移動(dòng)棧指針一格再存入;取出時(shí)可以直接取出,然后再移動(dòng)棧指針
  增棧:棧指針移動(dòng)時(shí)向地址增加的方向移動(dòng)的棧
  減棧:棧指針移動(dòng)時(shí)向地址減小的方向移動(dòng)的棧

ldmia r0, {r2 - r3}
ldmiar0!, {r2 - r3}

感嘆號(hào)的作用就是r0的值在ldm過程中發(fā)生的增加或者減少最后寫回到r0去,也就是說ldm時(shí)會(huì)改變r(jià)0的值。

ldmfd sp!, {r0 - r6, pc}
ldmfdsp!, {r0 - r6, pc}^

^的作用:在目標(biāo)寄存器中有pc時(shí),會(huì)同時(shí)將spsr寫入到cpsr,一般用于從異常模式返回。

總結(jié)

  批量讀取或?qū)懭雰?nèi)存時(shí)要用ldm/stm指令
  各種后綴以理解為主,不需記憶,最常見的是stmia和stmfd
  謹(jǐn)記:操作棧時(shí)使用相同的后綴就不會(huì)出錯(cuò),不管是滿棧還是空棧、增棧還是減棧

 

偽指令不是指令,偽指令和指令的根本區(qū)別是經(jīng)過編譯后會(huì)不會(huì)生成機(jī)器碼。
偽指令的意義在于指導(dǎo)編譯過程。
偽指令是和具體的編譯器相關(guān)的,我們使用gnu工具鏈,因此學(xué)習(xí)gnu環(huán)境下的匯編偽指令。

gnu匯編中的一些符號(hào)

@ 用來做注釋??梢栽谛惺滓部梢栽诖a后面同一行直接跟,和C語言中//類似
# 做注釋,一般放在行首,表示這一行都是注釋而不是代碼。
:以冒號(hào)結(jié)尾的是標(biāo)號(hào)
. 點(diǎn)號(hào)在gnu匯編中表示當(dāng)前指令的地址
# 立即數(shù)前面要加#或$,表示這是個(gè)立即數(shù)

常用gnu偽指令

.global _start@ 給_start外部鏈接屬性
.section .text@ 指定當(dāng)前段為代碼段
.ascii .byte .short .long .word
.quad .float .string @ 定義數(shù)據(jù)
.align 4@ 以16字節(jié)對(duì)齊
.balignl 16 0xabcdefgh @ 16字節(jié)對(duì)齊填充

偶爾

.end@標(biāo)識(shí)文件結(jié)束
.include@ 頭文件包含
.arm / .code32@聲明以下為arm指令
.thumb / .code16@聲明以下為thubm指令

最重要的幾個(gè)偽指令

ldr大范圍的地址加載指令
adr小范圍的地址加載指令
adrl中等范圍的地址加載指令
nop空操作

ARM中有一個(gè)ldr指令,還有一個(gè)ldr偽指令
一般都使用ldr偽指令而不用ldr指令

adr與ldr

adr編譯時(shí)會(huì)被1條sub或add指令替代,而ldr編譯時(shí)會(huì)被一條mov指令替代或者文字池方式處理;
adr總是以PC為基準(zhǔn)來表示地址,因此指令本身和運(yùn)行地址有關(guān),可以用來檢測(cè)程序當(dāng)前的運(yùn)行地址在哪里
ldr加載的地址和鏈接時(shí)給定的地址有關(guān),由鏈接腳本決定。

 

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
30
int a;
while(1);
flag:
b flag
b .
IRQ_STACK_START:
.word   0x0badc0de
等價(jià)于 unsigned int IRQ_STACK_START = 0x0badc0de;
.align 4    @ 16字節(jié)對(duì)齊
.align 2    @ 4字節(jié)對(duì)齊
.balignl 16, 0xdeadbeef @ 對(duì)齊 + 填充
b表示位填充;align表示要對(duì)齊;l表示long,以4字節(jié)為單位填充;16表示16字節(jié)對(duì)齊;0xdeadbeef是用來填充的原料。
0x00000008: .balignl 16, 0xdeadbeef
0x0000000c  0xdeadbeef
0x00000010: 下一條指令
ldr指令:  ldr r0, #0xff
偽指令:    ldr r0, =0xfffl @涉及到合法/非法立即數(shù),涉及到ARM文字池
adr和ldr的差別:ldr加載的地址在鏈接時(shí)確定,而adr加載的地址在運(yùn)行時(shí)確定;所以我們可以通過adr和ldr加載的地址比較來判斷當(dāng)前程序是否在鏈接時(shí)指定的地址運(yùn)行。

  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    国产黄色高清内射熟女视频| 老司机精品线观看86| 亚洲乱码av中文一区二区三区| 一区二区欧美另类稀缺| 人妻内射在线二区一区| 日韩黄色大片免费在线| 中文字幕乱子论一区二区三区| 国产免费成人激情视频| 熟女免费视频一区二区| 亚洲精品成人综合色在线| 两性色午夜天堂免费视频| 黄片在线观看一区二区三区| 国产精品成人又粗又长又爽| 色婷婷久久五月中文字幕| 91精品国自产拍老熟女露脸| 字幕日本欧美一区二区| 国产免费一区二区不卡| 欧美国产精品区一区二区三区| 中文久久乱码一区二区| 精品国产亚洲免费91| 日本精品理论在线观看| 日韩精品一区二区亚洲| 久久经典一区二区三区| 亚洲熟女诱惑一区二区| av在线免费播放一区二区| 高清免费在线不卡视频| 91午夜少妇极品福利| 国产内射一级一片内射高清| 亚洲一区二区精品福利| 日韩不卡一区二区在线| 丰满的人妻一区二区三区| 精品国产91亚洲一区二区三区 | 在线观看免费视频你懂的| 欧美美女视频在线免费看| 国产精品激情在线观看| 黄片在线免费观看全集| 国内真实露脸偷拍视频| 国产伦精品一一区二区三区高清版| 成年男女午夜久久久精品| 日本黄色美女日本黄色| 亚洲精品偷拍视频免费观看|