㈠ ARM匯編語言由哪些指令組成它們之間的區別是什麼
機器指令能被處理器直接執行,而匯編指令、偽指令和宏指令不能。機器指令包括ARM指令集和Thumb指令集 。
偽指令是在源程序匯編期間,由匯編編譯器處理。其作用是為匯編程序完成准備工作。
宏指令在程序中用於調用宏,宏是一段獨立的程序代碼;在程序匯編時,對宏調用進行展開,用宏體代替宏指令。
㈡ ARM STM32 嵌入式 匯編指令LDMIA用法
LDM是多寄存器存取的意思,IA表示數據傳輸後地址增加(increase
after);(IB:increase
before,
DA:
decrease
after,
DB:
decrease
before)
後面參數以「,」分隔,第一個參數是首地址;第二個參數是寄存器列表,並以「{}」括起來。
具體的例子:
LDMIA
R0!,
{R1-R4}
R0表示要操作的存儲空間首地址,要操作的數據個數由寄存器列表決定,現在是R1到R4,共4個數據(每個數據是32bits的)
具體:地址為R0的存儲空間中的數據賦值給R1
地址為R0+4的存儲空間中的數據賦值給R2
地址為R0+8的存儲空間中的數據賦值給R3
地址為R0+12的存儲空間中的數據賦值給R4
所有的示例指令執行前的存儲空間和寄存器情況:
mem32[0x1000C]
=
0x04
mem32[0x10008]
=
0x03
mem32[0x10004]
=
0x02
mem32[0x10000]
=
0x01
r0
=
0x00010000
r1
=
0x00000000
r3
=
0x00000000
r4
=
0x00000000
執行後存儲空間不變,寄存器變化:
r0
=
0x00010010
r1
=
0x01
r2
=
0x02
r3
=
0x03
r4
=
0x04
㈢ ARM1到ARM7 ARM指令集 都一樣嗎(匯編指令)
沒聽說過ARM1。但對ARM來說有兩大類匯編指令:ARM指令和thumb指令。thumb指令有16和32位,ARM指令位32位。對每一類來說,不用去關心解碼實現的話,總體是一樣的。
我所知道的就是V4之前沒設么區別,V4過後有稍稍區別,特別是V7給原來的有所改變,有的指令功能改變,有的指令不在有效,畢竟V7後都以Cortex命名,但該變不是很大。要詳細的資料,去看ARMARM手冊和ARMtrm手冊。
㈣ ARM中的匯編指令ASR指令MOV R0, R1, ASR#2
因為首先ASR是「算術」右移指令,因此用它來操作數據時,指令會認為被操作的數是有符號數,而二進制中有符號數的最高位即為符號位。因此為了保留數據符號,用符號位來填充因移位而導致的空缺位。舉例是這樣的:
MOV R1, 0x90000000;
MOV R0, R1, ASR #2;
//因為R1裡面的最高位元組是0x90,也就是二進制10010000,又是算數右移,所以會用最高位這個'1'填充空出來的位,移位完也就成了11100100_00,所以放到R0裡面成了0xE4000000。
㈤ ARM中匯編指令的問題
對,沒錯,loop就和C語言裡面goto的那個標號是一樣的,雖然在編寫程序時只是一個標號,但是其深層意思,也就是其編譯後的結果其實是一個地址,比如0x2000_1010。
你的上述程序解釋如下:
ldrb ch , [src] , #1 ;以src中的值為地址,從該地址處取1位元組數據到ch,再將src加1
strb ch , [dest] , #1 ;以dest中值為地址,將ch中1位元組數存儲在此處,再將dest加1
cmp ch , #0 ;比較ch和0的大小
bne loop ;如果ch不為0(注意這個"ne"),則跳至loop執行
很明顯,這是一個字元串拷貝程序,從src地址處拿來,一位元組一位元組放到dest去,然後一邊進行判斷,看是否已拷貝到最後的結尾字元'0',如果沒到,那麼跳到loop處繼續循環執行,如果已到,則繼續往下執行。雖然你程序里沒寫loop標號位置,但應該是在ldrb指令前面,以達到循環的效果。
㈥ ARM匯編指令
應該是mov r0, #0x18吧
我覺得這兩條語句與swi並不相干,可能只是傳遞參數用的,並不是說swi一定要先這么設置
㈦ 在arm的匯編程序中有哪幾種偽指令
在ARM匯編語言程序里,有一些特殊指令助記符,這些助記符與指令系統的助記符不同,沒有相對應的操作碼,通常稱這些特殊指令助記符為偽指令,他們所完成的操作稱為偽操作。偽指令在源程序中的作用是為完成匯編程序作各種准備工作的,這些偽指令僅在匯編過程中起作用,一旦匯編結束,偽指令的使命就完成。
在ARM的匯編程序中,有如下幾種偽指令:符號定義偽指令、數據定義偽指令、匯編控制偽指令、宏指令以及其他偽指令。
4.1.1 符號定義(Symbol Definition)偽指令
符號定義偽指令用於定義ARM匯編程序中的變數、對變數賦值以及定義寄存器的別名等操作。常見的符號定義偽指令有如下幾種:
— 用於定義全局變數的GBLA、GBLL和GBLS。
— 用於定義局部變數的LCLA、LCLL和LCLS。
— 用於對變數賦值的SETA、SETL、SETS。
— 為通用寄存器列表定義名稱的RLIST。
1、 GBLA、GBLL和GBLS
語法格式:
GBLA(GBLL或GBLS) 全局變數名
GBLA、GBLL和GBLS偽指令用於定義一個ARM程序中的全局變數,並將其初始化。其中:
GBLA偽指令用於定義一個全局的數字變數,並初始化為0;
GBLL偽指令用於定義一個全局的邏輯變數,並初始化為F(假);
GBLS偽指令用於定義一個全局的字元串變數,並初始化為空;
由於以上三條偽指令用於定義全局變數,因此在整個程序范圍內變數名必須唯一。
使用示例:
GBLA Test1 ;定義一個全局的數字變數,變數名為Test1
Test1 SETA 0xaa ;將該變數賦值為0xaa
GBLL Test2 ;定義一個全局的邏輯變數,變數名為Test2
Test2 SETL {TRUE} ;將該變數賦值為真
GBLS Test3 ;定義一個全局的字元串變數,變數名為Test3
Test3 SETS 「Testing」 ;將該變數賦值為「Testing」
2、 LCLA、LCLL和LCLS
語法格式:
LCLA(LCLL或LCLS) 局部變數名
LCLA、LCLL和LCLS偽指令用於定義一個ARM程序中的局部變數,並將其初始化。其中:
LCLA偽指令用於定義一個局部的數字變數,並初始化為0;
LCLL偽指令用於定義一個局部的邏輯變數,並初始化為F(假);
LCLS偽指令用於定義一個局部的字元串變數,並初始化為空;
以上三條偽指令用於聲明局部變數,在其作用范圍內變數名必須唯一。
使用示例:
LCLA Test4 ;聲明一個局部的數字變數,變數名為Test4
Test3 SETA 0xaa ;將該變數賦值為0xaa
LCLL Test5 ;聲明一個局部的邏輯變數,變數名為Test5
Test4 SETL {TRUE} ;將該變數賦值為真
LCLS Test6 ;定義一個局部的字元串變數,變數名為Test6
Test6 SETS 「Testing」 ;將該變數賦值為「Testing」
3、 SETA、SETL和SETS
語法格式:
變數名 SETA(SETL或SETS) 表達式
偽指令SETA、SETL、SETS用於給一個已經定義的全局變數或局部變數賦值。
SETA偽指令用於給一個數學變數賦值;
SETL偽指令用於給一個邏輯變數賦值;
SETS偽指令用於給一個字元串變數賦值;
其中,變數名為已經定義過的全局變數或局部變數,表達式為將要賦給變數的值。
使用示例:
LCLA Test3 ;聲明一個局部的數字變數,變數名為Test3
Test3 SETA 0xaa ;將該變數賦值為0xaa
LCLL Test4 ;聲明一個局部的邏輯變數,變數名為Test4
Test4 SETL {TRUE} ;將該變數賦值為真
4、 RLIST
語法格式:
名稱 RLIST {寄存器列表}
RLIST偽指令可用於對一個通用寄存器列表定義名稱,使用該偽指令定義的名稱可在ARM指令LDM/STM中使用。在LDM/STM指令中,列表中的寄存器訪問次序為根據寄存器的編號由低到高,而與列表中的寄存器排列次序無關。
使用示例:
RegList R www.hbbz08.com LIST {R0-R5,R8,R10} ;將寄存器列表名稱定義為RegList,可在ARM指令LDM/STM中通過該名稱訪問寄存器列表。
4.1.2 數據定義(Data Definition)偽指令
數據定義偽指令一般用於為特定的數據分配存儲單元,同時可完成已分配存儲單元的初始化。常見的數據定義偽指令有如下幾種:
— DCB 用於分配一片連續的位元組存儲單元並用指定的數據初始化。
— DCW(DCWU) 用於分配一片連續的半字存儲單元並用指定的數據初始化。
— DCD(DCDU) 用於分配一片連續的字存儲單元並用指定的數據初始化。
— DCFD(DCFDU)用於為雙精度的浮點數分配一片連續的字存儲單元並用指定的數據初始化。
— DCFS(DCFSU) 用於為單精度的浮點數分配一片連續的字存儲單元並用指定的數據初始化。
— DCQ(DCQU) 用於分配一片以8位元組為單位的連續的存儲單元並用指定的數據初始化。
— SPACE 用於分配一片連續的存儲單元
— MAP 用於定義一個結構化的內存表首地址
— FIELD 用於定義一個結構化的內存表的數據域
1、 DCB
語法格式:
標號 DCB 表達式
DCB偽指令用於分配一片連續的位元組存儲單元並用偽指令中指定的表達式初始化。其中,表達式可以為0~255的數字或字元串。DCB也可用「=」代替。
使用示例:
Str DCB 「This is a test!」 ;分配一片連續的位元組存儲單元並初始化。
2、 DCW(或DCWU)
語法格式:
標號 DCW(或DCWU) 表達式
DCW(或DCWU)偽指令用於分配一片連續的半字存儲單元並用偽指令中指定的表達式初始化。其中,表達式可以為程序標號或數字表達式。。
用DCW分配的字存儲單元是半字對齊的,而用DCWU分配的字存儲單元並不嚴格半字對齊。
使用示例:
DataTest DCW 1,2,3 ;分配一片連續的半字存儲單元並初始化。
3、 DCD(或DCDU)
語法格式:
標號 DCD(或DCDU) 表達式
DCD(或DCDU)偽指令用於分配一片連續的字存儲單元並用偽指令中指定的表達式初始化。其中,表達式可以為程序標號或數字表達式。DCD也可用「&」代替。
用DCD分配的字存儲單元是字對齊的,而用DCDU分配的字存儲單元並不嚴格字對齊。
使用示例:
DataTest DCD 4,5,6 ;分配一片連續的字存儲單元並初始化。
4、 DCFD(或DCFDU)
語法格式:
標號 DCFD(或DCFDU) 表達式
DCFD(或DCFDU)偽指令用於為雙精度的浮點數分配一片連續的字存儲單元並用偽指令中指定的表達式初始化。每個雙精度的浮點數占據兩個字單元。
用DCFD分配的字存儲單元是字對齊的,而用DCFDU分配的字存儲單元並不嚴格字對齊。
使用示例:
FDataTest DCFD 2E115,-5E7 ;分配一片連續的字存儲單元並初始化為指定的雙精度數。
5、 DCFS(或DCFSU)
語法格式:
標號 DCFS(或DCFSU) 表達式
DCFS(或DCFSU)偽指令用於為單精度的浮點數分配一片連續的字存儲單元並用偽指令中指定的表達式初始化。每個單精度的浮點數占據一個字單元。
用DCFS分配的字存儲單元是字對齊的,而用DCFSU分配的字存儲單元並不嚴格字對齊。
使用示例:
FDataTest DCFS 2E5,-5E-7 ;分配一片連續的字存儲單元並初始化為指定的單精度數。
6、 DCQ(或DCQU)
語法格式:
標號 DCQ(或DCQU) 表達式
DCQ(或DCQU)偽指令用於分配一片以8個位元組為單位的連續存儲區域並用偽指令中指定的表達式初始化。
用DCQ分配的存儲單元是字對齊的,而用DCQU分配的存儲單元並不嚴格字對齊。
使用示例:
DataTest DCQ 100 ;分配一片連續的存儲單元並初始化為指定的值。
7、 SPACE
語法格式:
標號 SPACE 表達式
㈧ arm常用幾個匯編語言的程序
一。從一數到十
COUNT EQU 0x30003100 ;定義變數COUNT的基地址 AREA Example1,CODE,READONLY;聲明代碼段Example1為只讀 ENTRY ;標識程序入口
CODE32 ;聲明32位ARM指令 START LDR R1,=COUNT ;將0X30003100賦給R1 MOV R0,#0 ;執行R0=0
STR R0,[R1] ;存儲R0寄存器的數據到R1指向的存儲單元 LOOP LDR R1,=COUNT ;將0X30003100賦給R1
LDR R0,[R1] ;將R1中的數值作為地址,取出此地址中的數據保存到R0中 ADD R0,R0,#1 ;執行R0=R0+1
CMP R0,#10 ;將R0與10進行比較
MOVHS R0,#0 ;若R0大於等於10,則R0=0
STR R0,[R1] ;存儲R0寄存器的數據到R1指向的地址單元 B LOOP ;跳轉到LOOP
END ;匯編文件結束
二,9的8次冪
X EQU 9 ;初始化X為9 n EQU 8 ;初始化N為8
AREA Example3,CODE,READONLY ;生明代碼段Example3為只讀 ENTRY ;標識程序入口路
CODE32 ;聲明32位ARM指令
START LDR SP,=0x30003F00 ;把0x30003F00 賦給SP(R13) LDR R0,=X ;把9賦給R0 LDR R1,=n ;把8賦給R1
BL POW ;跳轉到POW,並把下一條指令地址存入到R14中 HALT B HALT ;等待跳轉
POW STMFD SP!,{R1-R12,LR} ;將R1-R12入棧,滿遞減堆棧 MOVS R2,R1 ;將R1賦給R2,並影響標志位 MOVEQ R0,#1 ;若Z=1,則R0=1
BEQ POW_END ;若Z=1,跳轉到POW_END MOV R1,R0 ;將R0中值賦給R1 SUB R2,R2,#1 ;將R2-1的只賦給R2 POW_L1 BL DO_MUL ;跳轉到DO-MUL,並把下一條指令地址存入R14中 SUBS R2,R2,#1 ;將R2-1的值賦給R2,並影響標志位 BNE POW_L1 ;若Z=0,跳轉到POW_L1
POW_END LDMFD SP!,{R1-R12,PC} ;數據出棧,存入到R1-R12,PC中 DO_MUL MUL R0,R1,R0 ;把R1*R0的值賦給R0 MOV PC,LR ;LR中的值賦給PC END ;匯編結束
三:從一一直加到一百
程序清單(一) C 語言實驗參考程序
#define uint8 unsigned char ;定義一個無符號字元常量uint8 #define uint32 unsigned int ;定義一個無符號整型常量unint32
#define N 100 ;定義一個常量N=100(宏定義,100用N代替) uint32 sum; ;定義sum為無符號整型常量(聲明一個unsigned int型的變數sum) void Main(void) ;主函數
{uint32 i; ;定義無符號整型常量i(聲明一個unsigned int型的變數i) sum=0; ;sum初始值為0
for(i=0;i<=N;i++) ;i在N內自增加1(i從0開始,i<=N時循環成立) {sum+=i;} ;把sum+i賦給sum while(1); ;為真循環 }
程序清單(二) 簡單的啟動代碼
IMPORT |Image$$RO$$Limit | ;R0輸出段存儲區域界線 IMPORT |Image$$RW$$Base | ;RW輸出段運行時起始地址 IMPORT |Image$$ZI$$Base | ;ZI輸出段運行時起始地址 IMPORT |Image$$ZI$$Limit | ;ZI輸出段存儲區域界線 IMPORT Main ;主函數
AREA Start,CODE,READONLY ;聲明代碼段start,為只讀 ENTRY ;程序入口
CODE32 ;聲明32位ARM指令 Reset LDR SP,=0x40003f00 ;將0x40003f00賦給SP
LDR R0,=|Image$$RO$$Limit| ;將R0輸出段存儲區域界線賦給R0 LDR R1,=|Image$$RW$$Base | ;將RW輸出段運行時起始地址賦給R1 LDR R3,=|Image$$ZI$$Base | ;將ZI輸出段運行時起始地址賦給R3 CMP R0,R1 ;比較R0和R1,相等Z=1,反之Z=0 BEQ LOOP1 ;若Z=1,則跳到LOOP1
LOOP0 CMP R1,R3 ;比較R1和R3,若R1<r3,c=0
LDRCC R2,[R0],#4 ;若C=0,讀取R0地址單元內容並且存入R2,且R0=R0+4 STRCC R2,[R1],#4 ;若C=0,讀取R2中的數據存入R1,且R1=R1+4 BCC LOOP0 ;若C=0,跳轉到LOOP0
LOOP1 LDR R1,=|Image$$ZI$$Limit| ;將ZI輸出段存儲區域賦給R1 MOV R2,#0 ;把0賦給R2
LOOP2 CMP R3,R1 ;比較R1和R3,若R1<r3,c=0 strcc="" r2,[r3],#4="" ;若c="0,將R2中數據保存到內存單元R3中,且R3=R3+4" bcc="" loop2="" b="" main="" ;跳轉到主程序="" end="" ;匯編結束=""
四、程序清單(一) C 語言調用匯編的參考程序
#define uint8 unsigned char ;定義一個無符號字元常量uint8 #define uint32 unsigned int ;定義一個無符號整型常量.uint32
extern uint32 Add(uint32 x,uint32 y); //聲明子程序Add為一個無符號整型常量,它為2個無符號整型常量x,y的和
uint32 sum; ;定義sum為無符號整型常量 void Main(void) ;無返回主程序
{sum=Add(555,168); ;sum等於555+168 while(1); ;為真循環 }
程序清單(二) 匯編加法函數程序
EXPORT Add ;聲明子程序Add方便調用 AREA Start,CODE,READONLY ;聲明代碼段start,為只讀 ENTRY ;程序入口
CODE32 ;聲明32位ARM指令
Add ADD R0,R0,R1 ;將R0+R1值賦給R0 MOV PC,LR ;將LR值賦給PC
㈨ ARM匯編指令中什麼是有效立即數
要知道在ARM的體系結構中一條匯編指令的大小是32位,佔一個字(4個位元組大小),典型的ARM指令都是有統一的編碼格式的,如下圖所示:
一條指令的後12位(bit11~0),是指令中立即數佔用的位數,,其中這個12位又分為2部分,前7~0位是數值部分,後11~8位是前7~0位要進行移位操作的移位數,也就是說如果一個立即數小於0xFF(255)那麼直接用前7~0位表示即可,此時不用移位,11~8位的rotate_Imm等於0,如果前八位immed_8的數值大小了255,那麼就看這個數是否能有immed_8中的某個數移位rotate_imm位形成的,說起來很拗口。如果是,那麼這個立即數就是有效的,否則就是無效的。比如0xFF1不是合法的,而0xFF0就是合法有效數字。
㈩ ARM 匯編語言指令
ARM處理器有9種定址方式:
1、寄存器定址,2、立即定址,3、寄存器器移位定址,4、寄存器間接定址,5、基址定址,6、多寄存器定址,7、堆棧定址,8、塊拷貝定址,9、相對定址。
ARM指令集:ARM指令基本格式如下:
<OPCODE>{<COND>}{S} <Rd> ,<Rn>{,<OPERAND2>}
其中<>的內容是必須的,{}的內容是可選的。OPCODE指令助記符。