原文:ARM匯編指令 - - 博客園
ARM匯編程序特點:
l所有運算處理都是發生通用寄存器(一般是R0~R14)的之中.所有存儲器空間(如C語言變量的本質就是一個存儲器空間上的幾個BYTE).的值的處理,都是要傳送到通用寄存器來完成.因此代碼中大量看到LDR,STR指令來傳送值.
lARM匯編語句中.當前語句很多時候要隱含的使用上一句的執行結果.而且上一句的執行結果,是放在CPSR寄存器里,(比如說進位,為0,為負…)
CMP R0,R1
BNE
比如上一句,BNE隱含的使用的上一句CMP執行結果.NE后綴表示使用Z標志位.兩句合起來的意思就是,如果R0,R1的值不相等,就跳轉到處執行.
注意,PC=R15,CPSR=R16,
ARM偽指令不是必須的,但是一個完整沒有偽指令幾乎很難寫出來.
n比如一個程序至少包含 AREA和ENTRY,否則CPU都無法知道從哪里開始運行
lARM的屬于RISC,指令并不多,但是可以帶后綴表示擴展出不同用法,這里與X86匯編完全不同風格
n如BNE實際上是B指令的變種,本質還同一類指令.只是多一個對CPSR的Z標志位的判斷。
ARM常用指令,偽指令
ARM常用指令并不太多,因此使用閱讀ARM匯編代碼,并不太困難.以下是使用頻率最高的指令和偽指令,并不是完整的指令集的教材。詳細指令參見參考資料。
lB,BL
lMOV,MVN
lLDR,STR
lADD,SUB,ADC,SBC,MUL
lAND,ORR,XOR,TST,BIC
lCMP
lLDM/STM
lnop
1.跳轉語句B,BL
程序流程的跳轉,在ARM程序中有兩種方法可以實現程序流程的跳轉指令用于實現
l使用專門的跳轉指令B
l直接向程序計數器PC寫入跳轉地址值
n這是幾乎是任何一種CPU必備的機器,PC表示CPU當前執行語句位置,改變PC的值,相當于實現程序跳轉
n如實現類似C語言的語句,就是用MOV PC,LR
n這里可以在任意4G的空間進行跳轉
B指令()表示無條件跳轉.
B main;跳轉到標號為main地代碼處
BL指令( with Link)表示帶返回值的跳轉.
BL比B多做一步,在跳轉前,BL會把當前位置保存在R14(即LR寄存器),當跳轉代碼結束后,用MOV PC,LR指令跳回來,這實際上就是C語言執行函數的用法,
匯編里調子程序都用BL,執行完子函數后,可以用MOV PC,LR跳回來.
BL delay;執行子函數或代碼段delay ,delay可以為C函數.
與MOV PC,XXX能在4G空間跳轉不同,B語句只能32M空間跳轉,(因為偏移量是一個有符號26bit的數值=32M)
2.傳輸數據指令MOV,MVN
nMOV(MOVE)指令可完成從另一個寄存器、被移位的寄存器或將一個立即數加載到目的寄存器
MOV R0,R1;把R1的值傳到R0
MOV R3,#3;把常數3傳給R3,MOV中用#表示常數,這個值不能超過
nMVN( MOVE )取反后再傳值,比MOV多了一步取反
MVN R0, #0;把0取反(即-1)傳給R0
MVN R1,R2;把R2的值取反傳給R1
3.加載/存儲指令,LDR,STR
nLDR,STR是用于寄存器和外部存儲器交換數據指令,注意與MOV的區別,后面只在寄存器或常數交換.
uLDR/STR可以采用多種尋址方式,以下只舉出使用頻率最高幾種用法
nLDR(load)用于把一個32Bit的WORD數據從外部存儲空間裝入到寄存器中
LDR R0,[R1]; R1的值當成地址,再從這個地址裝入數據到R0 (R0=*R1)
LDR R1,=;把地址的值裝入到R1中,LDR中用常數要用=打頭.(注意跟MOV的區別,MOV是#)
ldrr0, =(0R1
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 ;聲明一個全局的邏輯變量
SETL{TRUE};設置變量為{TRUE}
LCLA bitno;聲明一個算術變量
Bitno SETA 8;設變量值為8
l數據定義偽指令
定義一個內存空間,并用0初始化
{label }SPACE expr
SPACE 100;定義100字節長空間, char [100];
nDCB定義一個連續字節內存空間,用偽指令的表達式expr來初始化.一般可以用定義數據表格,或文字字符串.(這時等同于SETS),用于初始二進制
{label} DCB expr{,expr …}
Dest DCB -120,20,36,55;等同于 char Dest[]={-120,20,36,55};
nDCU定義的一段字的內存空間(DCB是字節),并用后面表達式初始化
DCU Reset;等同于DWORD []={Reset};
nMAP定一個結構化內存,相當于定義一個C結構
定義一個結構化內存的成員
MAP 0x00,R9;定義內存表,地址為R9
4;定義數據域Timer,長為4字
4;定義數據域,長為4字
100;定義數據域 ,長為100字
相當于C語言的定義:
{
DWORD Timer ;
DWORD ;
Char [100];
} R9;
11.雜項的偽指令
n字節對齊ALIGN