如何使用arm彙編指令實現結構化程式設計

時間 2021-10-25 21:56:28

1樓:匿名使用者

arm彙編程式特點:

l 所有運算處理都是發生通用暫存器(一般是r0~r14)的之中.所有儲存器空間(如c語言變數的本質就是一個儲存器空間上的幾個byte).的值的處理,都是要傳送到通用暫存器來完成.

因此**中大量看到ldr,str指令來傳送值.

l arm彙編語句中.當前語句很多時候要隱含的使用上一句的執行結果.而且上一句的執行結果,是放在cpsr暫存器裡,(比如說進位,為0,為負…)

cmp r0,r1

bne nomatch

比如上一句,bne隱含的使用的上一句cmp執行結果.ne字尾表示使用z標誌位.兩句合起來的意思就是,如果r0,r1的值不相等,就跳轉到nomatch處執行.

注意,pc=r15,cpsr=r16,

arm偽指令不是必須的,但是一個完整沒有偽指令幾乎很難寫出來.

n 比如一個程式至少包含readonly area和entry,否則cpu都無法知道從**開始執行

l arm的屬於risc,指令並不多,但是可以帶字尾表示擴充套件出不同用法,這裡與x86彙編完全不同風格

n 如bne實際上是b指令的變種,本質還同一類指令.只是多一個對cpsr的z標誌位的判斷。

arm常用指令,偽指令

arm常用指令並不太多,因此使用閱讀arm彙編**,並不太困難.以下是使用頻率最高的指令和偽指令,並不是完整的指令集的教材。詳細指令參見參考資料。

l b,bl

l mov,mvn

l ldr,str

l add,sub,adc,sbc,mul

l and,orr,xor,tst,bic

l cmp

l ldm/stm

l nop

1. 跳轉語句 b,bl

程式流程的跳轉,在 arm 程式中有兩種方法可以實現程式流程的跳轉指令用於實現

l 使用專門的跳轉指令 b

l 直接向程式計數器pc 寫入跳轉地址值

n 這是幾乎是任何一種cpu必備的機器,pc表示cpu當前執行語句位置,改變pc的值,相當於實現程式跳轉

n 如實現類似c語言的return 語句,就是用mov pc,lr

n 這裡可以在任意4g的空間進行跳轉

b指令(branch)表示無條件跳轉.

b main ;跳轉到標號為main地**處

bl指令(branch with link)表示帶返回值的跳轉.

bl比b多做一步,在跳轉前,bl會把當前位置儲存在r14(即lr暫存器),當跳轉**結束後,用mov pc,lr指令跳回來,這實際上就是c語言執行函式的用法,

彙編裡調子程式都用bl,執行完子函式後,可以用mov pc,lr跳回來.

bl delay ;執行子函式或**段delay ,delay可以為c函式.

與mov pc,***能在4g空間跳轉不同,b語句只能32m空間跳轉,(因為偏移量是一個有符號26bit的數值=32m)

2. 傳輸資料指令mov,mvn

n mov(move)指令可完成從另一個暫存器、被移位的暫存器或將一個立即數載入到目的暫存器

mov r0,r1 ; 把r1的值傳到r0

mov r3,#3 ;把常數3傳給r3,mov中用#表示常數,這個值不能超過

n mvn( move negative)取反後再傳值,比mov多了一步取反

mvn r0, #0 ;把0取反(即-1)傳給r0

mvn r1,r2 ;把r2的值取反傳給r1

3. 載入/儲存指令,ldr,str

n ldr,str是用於暫存器和外部儲存器交換資料指令,注意與mov的區別,後面只在暫存器或常數交換.

u ldr/str可以採用多種定址方式,以下只舉出使用頻率最高几種用法

n ldr(load)用於把一個32bit的word資料從外部儲存空間裝入到暫存器中

ldr r0,[r1]; r1的值當成地址,再從這個地址裝入資料到r0 (r0=*r1)

ldr r1,=0x30008000 ; 把地址0x30008000的值裝入到r1中,ldr中用常數要用=打頭.(注意跟mov的區別,mov是#)

ldr r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)

用位與的方法賦值

n str(store) 用於把一個暫存器的值存入外部儲存空間,是ldr的逆操作.

str r0,[r1] ; 把r0的值,存入到r1對應地址空間上(*r1 = r0)

str r0,=0x30008000 ;把r0中值存入到地址0x30008000

s2c2440的中cpu核心以外的模組的控制暫存器空間也是屬於外部空間,所以也得用如下指令ldr r0,=gpfdat

4. 算術運算指令,add/adc,sub/sbc ,mul

n add加法指令

add r0,r1,r2; r0=r1+r2

add r0,r1,#3 ;r0=r1+3

n adc帶進位加法指令,即除了加兩個數以外,還要把cpsr的c值也要帶進來

u 通常用於大數(超過32bit整數)相加,這時單用add不能處理,必須折成兩步,其中一步用adc.

u 以下是做64bit的加法

adds r0,r1,r2; r0=r1+r2,adds中s表示把進位結果寫入cpsr

adc r5,r3,r4 ;r5=r3+r4+c

n sub減法指令

sub r0,r1,r2; r0=r1-r2

sub r0,r1,#3 ;r0=r1-3

n sbc帶進位減法指令,即除了加兩個數以外,還要把cpsr的c值也要帶進來,類似adc

u 以下是做64bit的減法

subs r0,r1,r2; r0=r1-r2,subs中s表示把進位結果寫入cpsr

sbc r5,r3,r4 ;r5=r3-r4-c

n mul 乘法指令

mul r0,r1,r2; r0=r1*r2

mul r0,r1,#3 ;r0=r1*3

5. 位操作指令 and,orr, tst,bic

n and位與指令

and r0,r1,r2; r0=r1 & r2

and r0,r1,#0xff ;r0=r1 & 0xff

n orr位或指令

orr r0,r1,r2; r0=r1 | r2

orr r0,r1,#0xff ;r0=r1 | 0xff

n tst測試某一位是否為1,並把結果寫入cpsr,供下一句使用

tst r1,#0xffe; 等同於if(r1 & 0xffe)

tst r1,#%1;測試最低位是否為1,%表示二進位制

n bic清位操作

bic r0,r0,#0xf ; 等同於 r0 &=~(0xf)

bic r0,r0,#%1011 ; 該指令清除 r0 中的位 0 1 3,其餘的位保持; %表示是二進位制,0x表示十六進位制

6. 比較指令 cmp

n cmp比較兩個運算元,並把結果存入cpsr供下一句語句使用

cmp r0,r1; 比較r0,r1

7. 多暫存器語句傳輸指令,ldm,stm

類似於一次傳一個buffer到暫存器當中,或反過來.後面一般要接一個地址改變方法

n ldm 從buffer傳資料多個暫存器傳輸資料到

ldmia r0! , ;加r0指向的地址上連續空間的資料,儲存到r3-r9當中,!表示r0值更新,ia字尾表示按word遞增

ldmfd sp!,^;恢復現場,異常處理返回,^表示不允許在使用者模式下使用。

n stm 從暫存器列表向儲存空間傳值。

stmia r1!, ;將r3-r9的資料儲存到r1指向的地址上,r1值更新。

stmfd sp!,; 現場儲存,將r0~r7,lr入棧

stmfd sp!, ,把sp暫存器對慶的地址的值存到r8,r9當中.!表示最後的值寫入sp中。fd表示

8. arm指令的變形

大部分指令後位可以接 與s兩個特殊位來表示,對cpsr特殊的一些判斷

s,表示當前指令執行後把結果改寫cpsr

subs,adds

取決於具體條件,只有cpsr滿足指定條件時才指這一指令

beq 實際上b+ eq的條件執行.

addne 表示add +ne 才開始加.

9. arm指令的定址方式

定址方式是根據指令中給出的地址碼來定位真實的地址,arm中有9種定址方法

l 暫存器定址

直接用暫存器編號來定址,最為常用

mov r1,r2 ;r2->r1

l 立即數定址

即指令中的地址碼是運算元本身,可以立即取出使用,立即數前帶一個#表示,否則表示一個地址

subs r0,r0,#1 ;r0 -1 ->r0

注意與subs r0,r0,1區別

l 暫存器偏移定址

這是arm特有的定址模式,當第2運算元是暫存器,在執行操作之前,可以做一次移位操作

mov r0,r2,lsl #3 ;r2的邏輯左移3位,結果放入r0,即r0=r2*8

ands r1,r1,r2,lsl r3;rs的值左移r3位,然後和r1相與操作,結果放入r1

移位操作有lsl (邏輯左移),lsr(邏輯右移) ,asr(算術右移),ror(迴圈右移)rrx帶擴充套件的迴圈右移

l 暫存器間接定址

即暫存器中值是一個地址,用來取出定位到地址當中

ldr r2,[r0] ;把r0的值當成地址,取出相應值,賦給r2

l 基址定址

把暫存器的地址值加上一個偏移量

ldr r2,[r3,#0x0f]; r3中的值加上0x0f,從這個地址取出值賦給r@

l 相對定址

基址定址的變形,由pc暫存器提供基準地址,指令中地址段作為偏移量.兩者相加即是有效地址,以下是bl採用相對定址

bl next

…next

…mov pc,lr ;從子程式返回

10. ads arm的偽指令

類似於c語言的巨集,由彙編程式預處理.

l 符號定義指令

全域性變數定義 gbla ,gbll,gbls

局域變數定義 lcla,lcll,lcls

變數賦值seta,setl,sets

其中上述偽指令中,最後面的a表示給一個算術變數賦值,l表示用於給一個邏輯變數賦值,s表示給一個字串賦值

gbll codedbg; 宣告一個全域性的邏輯變數

codebg setl ; 設定變數為

lcla bitno; 宣告一個算術變數

bitno seta 8 ;設變數值為8

l 資料定義偽指令

n space 定義一個記憶體空間,並用0初始化

space expr

databuf space 100 ;定義100位元組長空間, unsigned char databuf[100];

n dcb 定義一個連續位元組記憶體空間,用偽指令的表示式expr來初始化.一般可以用定義資料**,或文字字串.(這時等同於sets),用於初始二進位制buffer

dcb expr

dest dcb -120,20,36,55 ;等同於 unsigned char dest=;

n dcu定義的一段字的記憶體空間(dcb是位元組),並用後面表示式初始化

_reset dcu reset ; 等同於 dword _reset=;

n map定一個結構化記憶體,相當於定義一個c結構

n filed 定義一個結構化記憶體的成員

map 0x00,r9 ; 定義記憶體表,地址為r9

timer field 4 ; 定義資料域timer,長為4字

attrib field 4 ; 定義資料域attrib,長為4字

string filed 100 ; 定義資料域string ,長為100字

相當於c語言的定義:

struct r9;

11. 雜項的偽指令

n 位元組對齊 align

align; 宣告4位元組對齊

n 定義一個數字常量定義 equ

name equ expr

pllcon equ 0xe01fc080;定義pllcon,類似於c的巨集或c++的常量

n 包含檔案 get和include

include lpc2106.inc

n nop 空指令

在彙編時會被arm的空操作代替,比如mov r0,r0,一般用於延時與佔位。

n 宣告一個外部符符號 import,extern

import,extern 向外部匯入一個符號,一般是外部程式全域性變數

n 條件編譯:。類似於c的#ifdef 之類定義。

格式 :[ 條件表示式

滿足條件分支

|不滿足條件分支

]示例1:

[ entry_bus_width=32 ;類似#if entry_bus_width=32

b changebigendian ;dcd 0xea000007

] ; 類似#endif

示例2: [ clkdiv_val>1 ; 類似#if clkdiv_val>1

bl mmu_setasyncbusmode

|;類似#else

bl mmu_setfastbusmode ; default value.

]; 類似#endif

示例3 [ thumbcode 類似#ifdef thumbcode

bx lr

| ;類似#else

mov pc,lr

] ;類似#endif

n 段定義 area

n 指令集定義 code16和code32

指示是thumb 指令集(壓縮指令集,每個指令16位)。還是普通32位指令集

n 彙編結束:end

n 程式入口entry

歐姆龍PLC的置位指令 復位指令如何使用

omron裡面允許set和rset同乙個位,但最好不要同乙個位址多次set或rset。如果多次set或rset,生效的只是程式裡面最後的乙個set或rset有效,也就是被執行。類似於此類警告的還有mov指令,如mov 4 d10,後面又來乙個mov 10 d10,不同的條件傳送資料到同乙個位址d10...

手機使用mhl同時使用otg功能如何實現

雪靈冰魂龍寒月 你的手機不支援無線顯示哪 次爾雲 手機版本需要4.4以上,連線otg線就可以了 手機怎樣才能實現mhl和otg功能同時使用?感謝! 不可以的,因為手機受限於體積和功耗,藉口不豐富,mhl和otg使用同一針腳,使用擴充套件插口也無法實現。希望能幫到你 如何讓手機支援mhl和otg 對使...

歐姆龍PLC的PID指令如何使用

首先你要建立pid控制的模型演算法,才能寫程式,同時要考慮到效率問題,具體的程式根據情況進行!p,i d引數都可以設定,另外你的工藝引數有無特殊的要求,可以採用限值法等,根據工藝要求做,對擾動的措施,手動自動的切換你都要考慮。歐姆龍plc怎樣用梯形圖編寫pid運算 不用pid指令模組 我主要用在雙閉...