一: 匯編指令格式
ARM 匯編器
的基本語法,這與 GCC匯編器
的語法有所不同驮履,整體編譯的流程如下所示;
二: 匯編代碼是怎么轉(zhuǎn)換為二進(jìn)制機(jī)器碼的
很簡(jiǎn)單: 轉(zhuǎn)換協(xié)議
例如 ??????
mov r1,#0xff
1110 00 1 1101 0 0000 0001 000011111111
復(fù)制代碼
11--0位
:操作數(shù)廉嚼,若為立即數(shù)則填該立即數(shù)的二進(jìn)制值玫镐,若為通用寄存器則填通用寄存器標(biāo)號(hào)的二進(jìn)制值15--12位
:標(biāo)明目的寄存器19--16位
:標(biāo)明第一個(gè)源操作數(shù)寄存器20
:表明該指令是否會(huì)影響程序狀態(tài)字寄存器。是則置一怠噪,否則置零24~21
:標(biāo)明指令的類型恐似。mov
是1101
25
:標(biāo)志shifter_operand
段存放的是立即數(shù)還是寄存器。若為寄存器則置零傍念,若為立即數(shù)則置一矫夷。27~26
:保留位葛闷,恒定為0031~28
:條件段mov
后面沒有跟條件,所以為1110
三: 匯編基本指令 - 方便查閱
英文的文檔我這里就不貼了 回頭大家自行去查閱
指令類型 | 指令寬度 | 指令 |
---|---|---|
Data operations |
16 | ADC, ADD, AND, ASR, BIC, CMN, CMP, CPY, EOR, LSL, LSR, MOV, MUL, MVN,NEG, ORR, ROR, SBC, SUB, TST, REV, REVH, REVSH, SXTB, SXTH, UXTB, and UXTH. |
Branches |
16 | B, B, BL, BX, and BLX. Note, no BLX with immediate. |
Load-store single |
16 | LDR, LDRB, LDRH, LDRSB, LDRSH, STR, STRB, STRH. |
Load-store multiple |
16 | LDMIA, POP, PUSH, and STMIA. |
Exception generating |
16 | BKPT stops in debug if debug enabled, fault if debug disabled. SVC faults to the SVCall handler. |
Data operations with immediate |
32 | ADC{S}. ADD{S}, CMN, RSB{S}, SBC{S}, SUB{S}, CMP, AND{S}, TST, BIC{S}, EOR{S}, TEQ, ORR{S}, MOV{S}, ORN{S}, and MVN{S}. |
Data operations with large immediate |
32 | MOVW, MOVT, ADDW, and SUBW. MOVW and MOVT have a 16-bit immediate. This means they can replace literal loads from memory. ADDW and SUBW have a 12-bit immediate. This means they can replace many from memory literal loads. |
Bit-field operations |
32 | BFI, BFC, UBFX, and SBFX. These are bitwise operations enabling control of position and size in bits. These both support C/C++ bit fields, in structs, in addition to many compare and some AND/OR assignment expressions. |
Data operations with three registers |
32 | ADC{S}. ADD{S}, CMN, RSB{S}, SBC{S}, SUB{S}, CMP, AND{S}, TST, BIC{S},EOR{S}, TEQ, ORR{S}, MOV{S}, ORN{S}, and MVN{S}. No PKxxx instructions. |
Shift operations |
32 | ASR{S}, LSL{S}, LSR{S}, RRX {S}, and ROR {S}. |
Miscellaneous |
32 | REV, REVH, REVSH, RBIT, CLZ, SXTB, SXTH, UXTB, and UXTH.Extension instructions same as corresponding v6 16-bit instructions. |
Table branch |
32 | TBB and TBH table branches for switch/case use. These are LDR with shifts and then branch. |
Multiply |
32 | MUL, MLA, and MLS. |
Multiply with 64-bit result |
32 | UMULL, SMULL, UMLAL, and SMLAL |
Load-store single |
32 | LDR, LDRB, LDRSB, LDRH, LDRSH, STR, STRB, STRH, and T variants. PLD and PLI are both hints and so act as a NOP. |
Load-store multiple |
32 | STM, LDM, LDRD, and STRD. |
Load-store exclusive |
32 | LDREX, STREX, LDREXB, LDREXH, STREXB, STREXH, CLREX. Fault if no local monitor. This is IMP DEF. LDREXD and STREXD are not included in this profile. |
Branches |
32 | B, BL, and B. No BLX (1) because always changes state. No BXJ. |
System |
32 | MSR(2) and MRS(2) replace MSR/MRS but also do more. These access the other stacks and also the status registers.CPSIE/CPSID 32-bit forms are not supported. No RFE or SRS. |
System |
16 | CPSIE and CPSID are quick versions of MSR(2) instructions and use the standard Thumb-2 encodings, but only permit use of i and f and not a. |
Extended32 |
32 | NOP (all forms), Coprocessor (MCR, MCR2, MCRR, MRC, MRC2, and MRRC), and YIELD (hinted NOP). Note, no MRS(1), MSR(1), or SUBS (PC return link). |
Combined branch |
16 | CBZ and CBNZ (Compare and Branch if register is Zero or Non-Zero). |
Extended |
16 | IT and NOP. This includes YIELD. |
Divide |
32 | SDIV and UDIV. 32/32 divides both signed and unsigned with 32-bit quotient result, no remainder, it can be derived by subtraction. Early out is permitted. |
Sleep |
16,32 | WFI, WFE, and SEV are in the class of hinted NOP instructions that control sleep behavior. |
Barriers |
32 | ISB, DSB, and DMB are barrier instructions that ensure certain actions have taken place before the next instruction is executed. |
Saturation |
32 | SSAT and USAT perform saturation on a register. They perform the following: Normalize the value using shift test for overflow from a selected bit position, the Q value. Set the xPSR Q bit if so, saturate the value if overflow detected. Saturation refers to the largest unsigned value or the largest/smallest signed value for the size selected. |
常見指令
b 指令
bl 指令
跳轉(zhuǎn)到標(biāo)號(hào)出執(zhí)行b.le
:判斷上面cmp的值是小于等于 執(zhí)行標(biāo)號(hào)口四,否則直接往下走b.ge
大于等于 執(zhí)行地址 否則往下b.lt
判斷上面camp的值是 小于 執(zhí)行后面的地址中的方法 否則直接往下走b.gt
大于 執(zhí)行地址 否則往下b.eq
等于 執(zhí)行地址 否則往下b.hi
比較結(jié)果是無符號(hào)大于孵运,執(zhí)行地址中的方法秦陋,否則不跳轉(zhuǎn)b.hs
指令是判斷是否無符號(hào)小于b.ls
指令是判斷是否無符號(hào)大于b.lo
指令是判斷是否無符號(hào)大于等于
ret 返回
mov x0,#0x10 -> x0 = 0x10
str w10 ,[sp]
將w10寄存器的值存到 sp椔剩空間內(nèi)存stp x0,x1,[sp.#0x10]*
: x0驳概、x1 的值存入 sp + 0x10orr x0赤嚼,wzr,#0x1
: x0 = wzr | 0x1stur w10 ,[sp]
將w10寄存器的值存到 sp棧空間內(nèi)存ldr w10 ,[sp]
w10 = sp棧內(nèi)存中的值ldp x0顺又,x1,[sp]
x0更卒、x1 = sp棧內(nèi)存中的值
adrp
通過基地址 + 偏移 獲得一個(gè)字符串(全局變量)
cbz
比較,為零則跳轉(zhuǎn)稚照;cbnz
: 比較蹂空,為非零則跳轉(zhuǎn)。cmp: 比較功能
例如 :cmp OPR1 , OPR2\. = (OPR1)-(OPR2)
16位數(shù)據(jù)操作指令
名字 | 功能 |
---|---|
ADC |
帶進(jìn)位加法(ADD with Carry) |
ADD |
加法 |
AND |
按位與果录。這里的按位與和C的”&”功能相同 |
ASR |
算術(shù)右移(Arithmetic Shift Right) |
BIC |
按位清零(把一個(gè)數(shù)跟另一個(gè)無符號(hào)數(shù)的反碼按位與) |
CMN |
負(fù)向比較(把一個(gè)數(shù)跟另一個(gè)數(shù)據(jù)的二進(jìn)制補(bǔ)碼相比較) |
CMP |
比較(Compare上枕,比較兩個(gè)數(shù)并且更新標(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指令返弹! |
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 |
無符號(hào)(Unsigned)擴(kuò)展一個(gè)字節(jié)(Byte)到 32位 |
UXTH |
無符號(hào)(Unsigned)擴(kuò)展一個(gè)半字(Half)到 32位 |
16位轉(zhuǎn)移指令
名字 | 功能 |
---|---|
B |
無條件轉(zhuǎn)移(Branch) |
B |
有條件(Condition)轉(zhuǎn)移 |
BL |
轉(zhuǎn)移并連接(Link)椅棺。用于呼叫一個(gè)子程序,返回地址被存儲(chǔ)在LR中 |
CBZ |
比較(Compare)穷蛹,如果結(jié)果為零(Zero)就轉(zhuǎn)移(只能跳到后面的指令) |
CBNZ |
比較土陪,如果結(jié)果非零(Non Zero)就轉(zhuǎn)移(只能跳到后面的指令) |
IT |
If-Then |
16位存儲(chǔ)器數(shù)據(jù)傳送指令
名字 | 功能 |
---|---|
LDR |
從存儲(chǔ)器中加載(Load)字到一個(gè)寄存器(Register)中 |
LDRH |
從存儲(chǔ)器中加載半(Half)字到一個(gè)寄存器中 |
LDRB |
從存儲(chǔ)器中加載字節(jié)(Byte)到一個(gè)寄存器中 |
LDRSH |
從存儲(chǔ)器中加載半字,再經(jīng)過帶符號(hào)擴(kuò)展后存儲(chǔ)一個(gè)寄存器中 |
LDRSB |
從存儲(chǔ)器中加載字節(jié)肴熏,再經(jīng)過帶符號(hào)擴(kuò)展后存儲(chǔ)一個(gè)寄存器中 |
STR |
把一個(gè)寄存器按字存儲(chǔ)(Store)到存儲(chǔ)器中 |
STRH |
把一個(gè)寄存器存器的低半字存儲(chǔ)到存儲(chǔ)器中 |
STRB |
把一個(gè)寄存器的低字節(jié)存儲(chǔ)到存儲(chǔ)器中 |
LDMIA |
加載多個(gè)字鬼雀,并且在加載后自增基址寄存器 |
STMIA |
存儲(chǔ)多個(gè)字,并且在存儲(chǔ)后自增基址寄存器 |
PUSH |
壓入多個(gè)寄存器到棧中 |
POP |
從棧中彈出多個(gè)值到寄存器中 |
其它16位指令
名字 | 功能 |
---|---|
SVC |
系統(tǒng)服務(wù)調(diào)用(Service Call) |
BKPT |
斷點(diǎn)(Break Point)指令蛙吏。如果調(diào)試被使能源哩,則進(jìn)入調(diào)試狀態(tài)(停機(jī))鞋吉。 |
NOP |
無操作(No Operation) |
CPSIE |
使能 PRIMASK(CPSIE i)/FAULTMASK(CPSIE f)——清零相應(yīng)的位 |
CPSID |
除能 PRIMASK(CPSID i)/FAULTMASK(CPSID f)——置位相應(yīng)的位 |
32位數(shù)據(jù)操作指令
名字 | 功能 |
---|---|
ADC |
帶進(jìn)位加法 |
ADD |
加法 |
ADDW |
寬加法(可以加 12 位立即數(shù)) |
AND |
按位與 |
ASR |
算術(shù)右移 |
BIC |
位清零(把一個(gè)數(shù)按位取反后,與另一個(gè)數(shù)邏輯與) |
BFC |
位段清零 |
BFI |
位段插入 |
CMN |
負(fù)向比較(把一個(gè)數(shù)和另一個(gè)數(shù)的二進(jìn)制補(bǔ)碼比較励烦,并更新標(biāo)志位) |
CMP |
比較兩個(gè)數(shù)并更新標(biāo)志位 |
CLZ |
計(jì)算前導(dǎo)零的數(shù)目 |
EOR |
按位異或 |
LSL |
邏輯左移 |
LSR |
邏輯右移 |
MLA |
乘加 |
MLS |
乘減 |
MOVW |
把 16 位立即數(shù)放到寄存器的底16位谓着,高16位清0 |
MOV |
加載16位立即數(shù)到寄存器(其實(shí)匯編器會(huì)產(chǎn)生MOVW) |
MOVT |
把 16 位立即數(shù)放到寄存器的高16位,低 16位不影響 |
MVN |
移動(dòng)一個(gè)數(shù)的補(bǔ)碼 |
MUL |
乘法 |
ORR |
按位或 |
ORN |
把源操作數(shù)按位取反后坛掠,再執(zhí)行按位或 |
RBIT |
位反轉(zhuǎn)(把一個(gè) 32 位整數(shù)先用2 進(jìn)制表達(dá)赊锚,再旋轉(zhuǎn)180度) |
REV |
對(duì)一個(gè)32 位整數(shù)做按字節(jié)反轉(zhuǎn) |
REVH/REV16 |
對(duì)一個(gè)32 位整數(shù)的高低半字都執(zhí)行字節(jié)反轉(zhuǎn) |
REVSH |
對(duì)一個(gè)32 位整數(shù)的低半字執(zhí)行字節(jié)反轉(zhuǎn),再帶符號(hào)擴(kuò)展成32位數(shù) |
ROR |
圓圈右移 |
RRX |
帶進(jìn)位的邏輯右移一格(最高位用C 填充屉栓,且不影響C的值) |
SFBX |
從一個(gè)32 位整數(shù)中提取任意的位段舷蒲,并且?guī)Х?hào)擴(kuò)展成 32 位整數(shù) |
SDIV |
帶符號(hào)除法 |
SMLAL |
帶符號(hào)長(zhǎng)乘加(兩個(gè)帶符號(hào)的 32 位整數(shù)相乘得到 64 位的帶符號(hào)積,再把積加到另一個(gè)帶符號(hào) 64位整數(shù)中) |
SMULL |
帶符號(hào)長(zhǎng)乘法(兩個(gè)帶符號(hào)的 32 位整數(shù)相乘得到 64位的帶符號(hào)積) |
SSAT |
帶符號(hào)的飽和運(yùn)算 |
SBC |
帶借位的減法 |
SUB |
減法 |
SUBW |
寬減法友多,可以減 12 位立即數(shù) |
SXTB |
字節(jié)帶符號(hào)擴(kuò)展到32位數(shù) |
TEQ |
測(cè)試是否相等(對(duì)兩個(gè)數(shù)執(zhí)行異或牲平,更新標(biāo)志但不存儲(chǔ)結(jié)果) |
TST |
測(cè)試(對(duì)兩個(gè)數(shù)執(zhí)行按位與,更新Z 標(biāo)志但不存儲(chǔ)結(jié)果) |
UBFX |
無符號(hào)位段提取 |
UDIV |
無符號(hào)除法 |
UMLAL |
無符號(hào)長(zhǎng)乘加(兩個(gè)無符號(hào)的 32 位整數(shù)相乘得到 64 位的無符號(hào)積域滥,再把積加到另一個(gè)無符號(hào) 64位整數(shù)中) |
UMULL |
無符號(hào)長(zhǎng)乘法(兩個(gè)無符號(hào)的 32 位整數(shù)相乘得到 64位的無符號(hào)積) |
USAT |
無符號(hào)飽和操作(但是源操作數(shù)是帶符號(hào)的) |
UXTB |
字節(jié)被無符號(hào)擴(kuò)展到32 位(高24位清0) |
UXTH |
半字被無符號(hào)擴(kuò)展到32 位(高16位清0) |
32位存儲(chǔ)器數(shù)據(jù)傳送指令
名字 | 功能 |
---|---|
LDR |
加載字到寄存器 |
LDRB |
加載字節(jié)到寄存器 |
LDRH |
加載半字到寄存器 |
LDRSH |
加載半字到寄存器纵柿,再帶符號(hào)擴(kuò)展到 32位 |
LDM |
從一片連續(xù)的地址空間中加載多個(gè)字到若干寄存器 |
LDRD |
從連續(xù)的地址空間加載雙字(64 位整數(shù))到2 個(gè)寄存器 |
STR |
存儲(chǔ)寄存器中的字 |
STRB |
存儲(chǔ)寄存器中的低字節(jié) |
STRH |
存儲(chǔ)寄存器中的低半字 |
STM |
存儲(chǔ)若干寄存器中的字到一片連續(xù)的地址空間中 |
STRD |
存儲(chǔ)2 個(gè)寄存器組成的雙字到連續(xù)的地址空間中 |
PUSH |
把若干寄存器的值壓入堆棧中 |
POP |
從堆棧中彈出若干的寄存器的值 |
32位轉(zhuǎn)移指令
名字 | 功能 |
---|---|
B |
無條件轉(zhuǎn)移 |
BL |
轉(zhuǎn)移并連接(呼叫子程序) |
TBB |
以字節(jié)為單位的查表轉(zhuǎn)移。從一個(gè)字節(jié)數(shù)組中選一個(gè)8位前向跳轉(zhuǎn)地址并轉(zhuǎn)移 |
TBH |
以半字為單位的查表轉(zhuǎn)移启绰。從一個(gè)半字?jǐn)?shù)組中選一個(gè)16 位前向跳轉(zhuǎn)的地址并轉(zhuǎn)移 |
其它32位指令
名字 | 功能 |
---|---|
LDREX |
加載字到寄存器昂儒,并且在內(nèi)核中標(biāo)明一段地址進(jìn)入了互斥訪問狀態(tài) |
LDREXH |
加載半字到寄存器,并且在內(nèi)核中標(biāo)明一段地址進(jìn)入了互斥訪問狀態(tài) |
LDREXB |
加載字節(jié)到寄存器酬土,并且在內(nèi)核中標(biāo)明一段地址進(jìn)入了互斥訪問狀態(tài) |
STREX |
檢查將要寫入的地址是否已進(jìn)入了互斥訪問狀態(tài)荆忍,如果是則存儲(chǔ)寄存器的字 |
STREXH |
檢查將要寫入的地址是否已進(jìn)入了互斥訪問狀態(tài),如果是則存儲(chǔ)寄存器的半字 |
STREXB |
檢查將要寫入的地址是否已進(jìn)入了互斥訪問狀態(tài)撤缴,如果是則存儲(chǔ)寄存器的字節(jié) |
CLREX |
在本地的處理上清除互斥訪問狀態(tài)的標(biāo)記(先前由 LDREX/LDREXH/LDREXB做的標(biāo)記) |
MRS |
加載特殊功能寄存器的值到通用寄存器 |
MSR |
存儲(chǔ)通用寄存器的值到特殊功能寄存器 |
NOP |
無操作 |
SEV |
發(fā)送事件 |
WFE |
休眠并且在發(fā)生事件時(shí)被喚醒 |
WFI |
休眠并且在發(fā)生中斷時(shí)被喚醒 |
ISB |
指令同步隔離(與流水線和 MPU等) |
DSB |
數(shù)據(jù)同步隔離(與流水線刹枉、MPU 和cache等) |
DMB |
數(shù)據(jù)存儲(chǔ)隔離(與流水線、MPU 和cache等) |