ARM常用指令+源碼解讀


概念闡述:

AREA

段名 屬性1,屬性2

— CODE 屬性:用於定義代碼段,默認為READONLY 。

— DATA 屬性:用於定義數據段,默認為READWRITE 。

— READONLY 屬性:指定本段為只讀,代碼段默認為READONLY 。

— READWRITE 屬性:指定本段為可讀可寫,數據段的默認屬性為READWRITE 。

— ALIGN 屬性:使用方式為ALIGN表達式。在默認時,ELF(可執行連接文件)的代碼段和數據段是按字對齊的,表達式的取值范圍為0~31,相應的對齊方式為2表達式次方。

— COMMON 屬性:該屬性定義一個通用的段,不包含任何的用戶代碼和數據。各源文件中同名的COMMON段共享同一段存儲單元

ENTRY

ENTRY偽指令用於指定匯編程序的入口點。在一個完整的匯編程序中至少要有一個ENTRY(也可以有多個,當有多個ENTRY時,程序的真正入口點由鏈接器指定),但在一個源文件里最多只能有一個ENTRY(可以沒有)。

IMPORT

標識符表明要調用的函數為本模塊外部定義的

EXPORT

標識符表示本模塊中定時的符號可以為外部模塊使用

EQU

EQU 指令用於將一個數值或寄存器名賦給一個指定的符號名。

用法:①符號名 EQU 表達式

​ ②符號名 EQU 寄存器名

MOV

將源操作數source的值復制到target中去,source值不變

用法:MOV target,source

ADD

將后面的操作數加到前面操作數中

用法:ADD reg/mem reg/mem/imm

SUB

將前面的數減去后面的數,存到前面的寄存器中

用法:SUB reg/mem reg/mem/imm

LDR(指令

與MOV功能類似,相當於立即數沒有超過8位執行的MOV指令,使用時沒有等號

例1: ldr r0, 0x12345678 // 就是把0x12345678這個地址中的值存放到r0中。而mov不能干這個活,mov只能在寄存器之間移動數據,或者把立即數移動到寄存器中。
例2:ldr r0,r1 //表示把r1寄存器中的值放入r0
例3:ldr r0,[r1] // [r1]表示r1中值對應內存的地址,所以是把r1中的數當作一個地址,把這個地址中的值放入r0

LDR(偽指令

與MOV功能類似,相當於立即數沒有超過8位執行的MOV指令,使用時有等號

例1(立即數):LDR r0, =0x12345678 //把0x12345678這個地址寫到r0中

例2(標號): LDR r0, =_start //將指定標號的地址賦給r0

DCD

數據定義( Data Definition )偽指令

一般用於為特定的數據分配存儲單元,同時可完成已分配存儲單元的初始化。

用法:標號 DCD(或 DCDU) 表達式

CMP

(比較)指令執行從目的操作數中減去源操作數的隱含減法操作

用法:CMP destination,source

如果比較的是兩個無符號數,則零標志位和進位標志位表示的兩個操作數之間的關系如右表所示:

CMP結果 ZF CF
目的操作數 < 源操作數 0 1
目的操作數 > 源操作數 0 0
目的操作數 = 源操作數 1 0

如果比較的是兩個有符號數,則符號標志位、零標志位和溢出標志位表示的兩個操作數之間的關系如右表所示:

CMP結果 標志位
目的操作數 < 源操作數 SF ≠ OF
目的操作數 > 源操作數 SF=OF
目的操作數 = 源操作數 ZF=1

例1:

MOV ax, 5
CMP ax,10 ; ZF = 0 and CF = 1

例2:

MOV ax,1000
MOV cx,1000
CMP cx, ax ;ZF = 1 and CF = 0

例3:

MOV si,105
CMP si, 0 ; ZF = 0 and CF = 0

B,BL

跳轉。BL相當於C中的調用子函數,在跳轉的標號最后加上MOV PC,LR 就可以返回BL下一條指令。

BGE

GE是指令條件,意思就是greater or equal,大於或等於,似乎幾乎zd可以加到所有指令上。
BGE中的B是回branch,跳轉的意思,BGE就是大答於或等於才跳。

BEQ

BEQ(比較相等,EQ為相等) 在BEQ指令前應該有一條比較指令,比如CMP R0,R1 若R0=R1,則執行BEQ指令,否則不執行。

BNE

BNE: 數據跳轉指令,標志寄存器中Z標志位不等於零時, 跳轉到BNE后標簽處。

與b的區別:BNE指令,是個條件跳轉,即:是“不相等(或不為0)跳轉指令”。如果不為0就跳轉到后面指定的地址,繼續執行。

B 是最簡單的分支。一旦遇到一個 B 指令,ARM 處理器將立即跳轉到給定的地址,從那里繼續執行。

與BGE的區別:BNE指令會去查看狀態寄存器,當Z!=1的時候就跳轉到指定位置,BEQ功能與BNE剛好相反,Z==1的時候才跳轉到指定位置.

BX

跳轉並切換指令集。

bx lr的作用等同於mov pc,lr

可以使用MOV PC, LR或者BX LR來完成子程序返回。另外,也可以在在子程序入口處使用下面的指令將LR保存到棧中

LR

鏈接寄存器(用來存放子程序的返回地址) LR相當於指針變量,指令在內存中的地址。如果子程序再調用子程序,返前一次調用的子程序的返回地址要存儲棧內 。

N 當用兩個補碼表示的帶符號數進行運算時,N=1表示運算的結果為負數;N=0表示運算的結果為正數或零.
Z Z=1表示運算的結果為零,Z=0表示運算的結果非零。
C 可以有4種方法設置C的值:
加法運算(包括CMN):當運算結果產生了進位時(無符號數溢出),C=1,否則C=0。
減法運算(包括CMP):當運算時產生了借位時(無符號數溢出),C=0,否則C=1。
對於包含移位操作的非加/減運算指令,C為移出值的最后一位。
對於其它的非加/減運算指令,C的值通常不會改變。
V 可以有2種方法設置V的值:
對於加減法運算指令,當操作數和運算結果為二進制的補碼表示的帶符號數時,V=1表示符號位溢出
對於其它的非加/減運算指令,V的值通常不會改變。

DCD

用於分配一片連續的字存儲單元並用指定的數據初始化。

明白了一些概念咋們來實戰吧~

源碼解讀:

該程序實現了什么功能呢~?

;routine for find max value in a integer array.
;R1 is the counter of the loop.
;R2 is the pointer of the arraye element. R3 is the value of array element pointed by R2.
;R4 is alway pointing to the max element finded up now,and R5 is the value of the array element pointed by R4.
;在整數數組中查找最大值的例程。
;R1是循環的計數器。
;R2是arraye元素的指針。R3是R2指向的數組元素的值。
;R4總是指向現在找到的max元素,R5是R4指向的數組元素的值。
N EQU 10	;講N的值定義為10
    AREA findEX01,CODE,READONLY 
    ;這是段名為findEX01(findEX01),可讀可寫(READONLY)的代碼段(CODE)
    ENTRY	;程序開始
    EXPORT findnum	;findnum代碼塊可以在外部模塊使用
findnum		;函數名,該函數用於初始化寄存器R1~R5的值
    MOV R1,#N-1		;將N-1的值存放到寄存器R1中
    LDR R2,=finddata10		;將finddata10的首地址存到R2中
    LDR R3,[R2]		;將R2中的值作為地址,從該地址取出數據存到R3中,finddata10第一個元素的值為0x70,R3將存儲0x70
    MOV R4,R2		;將R2的值存放到R4中
    MOV R5,R3		;將R3的值存放到R5中,這兩步是為了從首地址開始遍歷嘛
findloop02		;函數名,該函數內前半部分用於R2指針遍歷數組中的連續單元,中間部分用於比較找出最大值,如果R2指向的值比R5大,將該值的地址存在R4中,該值存在R5中。
    ADD R2,R2,#4	;將R2中的值與4相加存到R2中:儲存一個數需要4字節,因此指向下一個數需要偏移4個字節
    LDR R3,[R2]		;將R2的值作為地址,從該地址取出數據存到R3中
    CMP R5,R3		;比較R5和R3的值
    BGE findskip	;當R5>R3時跳到findskip函數,R5<=R3時繼續執行
    MOV R4,R2		;將R2的值存到R4中
    MOV R5,R3		;將R3的值存到R5中
findskip		;函數名,用作循環,類似於for(i=9;i>=0;i--)
    SUB R1,R1,#1	;R1自減
    CMP R1,#0		;將R1的值與R0比較
    BNE findloop02	;當R1!=0時,跳轉到findloop02函數
    
    BX LR			;等同於 MOV pc,lr, 這里是完成子程序的返回
    
    AREA finddat0,DATA,READWRITE
    ;這是段名為finddat0(finddat0),可讀可寫(READONLY)的數據段(DATA)
finddata10 DCD 0x70,0x30,0x20,0x80,0x35,0x65,0x55,0x75,0x25,0x60
;分配一段連續的單元地址
	END				;結束模塊

所以!它就是開了個數組,找到了數組中的最大元素!寫了一晚上,甚至激動QAQ比前一篇文章好一些了,一丟丟基礎都沒花時間理清關系挺艱辛的qaq碎覺覺了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM