新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM匯編語(yǔ)言(4) 指令、偽操作、偽指令學(xué)習(xí)

ARM匯編語(yǔ)言(4) 指令、偽操作、偽指令學(xué)習(xí)

作者: 時(shí)間:2016-11-10 來(lái)源:網(wǎng)絡(luò) 收藏
LDR指令與LDR偽指令的4種形式:

LDR R0,[R1]:指令,將R1指向的內(nèi)存地址存放的內(nèi)容加載到R0中;

本文引用地址:http://m.butianyuan.cn/article/201611/317563.htm

LDR R0,LABEL:指令,將標(biāo)號(hào)LABEL所代表的內(nèi)存地址處存放的內(nèi)容加載到R0中;

LDR R0,=10000:偽指令,將常熟10000賦予R0,采用LDR指令+文字池的方式實(shí)現(xiàn);

LDR R0,=LABEL:偽指令,將標(biāo)號(hào)LABEL所代表的內(nèi)存地址賦予R0;

指令部分:

偽操作部分:

符號(hào)定義偽操作:定義變量,對(duì)變量進(jìn)行賦值,定義寄存器名稱(chēng)

GBLA:全局的算術(shù)變量,初始化為0;

GBLL:全局的邏輯變量,初始化為{FALSE};

GBLS:全局的串變量,初始化為“”;

LCLA:局部的算術(shù)變量,初始化為0;

LCLL:局部的邏輯變量,初始化為{FALSE};

LCLS:局部的串變量,初始化為“”;

SETA:給算術(shù)變量賦值;

SETL:給邏輯變量賦值;

SETS:給串變量賦值;

RLIST:為一個(gè)通用寄存器列表定義名稱(chēng);

CN:為一個(gè)協(xié)處理器的寄存器定義名稱(chēng);

CP:為一個(gè)協(xié)處理器定義名稱(chēng);

DN:為一個(gè)雙精度的VFP寄存器定義名稱(chēng);

SN:為一個(gè)單精度的VFP寄存器定義名稱(chēng);

FN:為一個(gè)FPA浮點(diǎn)寄存器定義名稱(chēng);

數(shù)據(jù)定義偽操作

LTORG:聲明一個(gè)數(shù)據(jù)緩沖池的開(kāi)始;

MAP:定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址,同義詞為^;

FIELD:定義一個(gè)結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域,同義詞#;

SPACE:分配一塊內(nèi)存單元,并用0初始化,同義詞%;

{label} SPACE exprexpr表示分配的內(nèi)存字節(jié)數(shù);

DCB:分配一段字節(jié)內(nèi)存單元,并用expr初始化之,同義詞=;

{label} DCB expr, {expr}...expr是-128~255的數(shù)值或字符串;

DCD,DCDU:分配一段字內(nèi)存單元,分配的內(nèi)存都是字對(duì)齊的,并用expr初始化之,同義詞&,DCDU分配的內(nèi)存單元不嚴(yán)格字對(duì)齊;

DCDO:分配一段字內(nèi)存單元,分配的內(nèi)存都是字對(duì)齊的,并將每個(gè)字單元的內(nèi)容初始化為expr標(biāo)號(hào)基于靜態(tài)基址寄存器R9的偏移量;

DCFD,DCFDU:

DCFS,DCFSU:

DCI:(ARM)分配一段字內(nèi)存單元,分配的內(nèi)存都是字對(duì)齊的,并用expr初始化;(Thumb)分配一段半字內(nèi)存單元,分配的內(nèi)存都是半字對(duì)齊的,并用expr初始化;

DCQ,DCQU:

DCW,DCWU:

匯編控制偽操作

IF,ELSE,ENDIF:根據(jù)條件將一段源代碼包括在匯編語(yǔ)言程序中或者將其排除在程序之外;

IF logical expression

instructions or directives

ELSE

instructions or directives

ENDIF

WHILE,WEND:根據(jù)條件重復(fù)匯編相同的或者幾乎相同的一段源代碼;

WHILE logical expression

instructions or directives

WEND

MACRO,MEND:定義宏定義體;

MEXIT:從宏中跳轉(zhuǎn)出去;

棧中數(shù)據(jù)幀描述偽操作;

信息報(bào)告?zhèn)尾僮鳎?/p>

其它偽操作:

CODE16,CODE32:

EQU:為數(shù)字常量,基于寄存器的值和程序中的標(biāo)號(hào)定義一個(gè)字符名稱(chēng),同義詞*;

name EQU expr {, type}

AREA:

ENTRY:

END:

ALIGN:

EXPORT:

GLOBAL:

IMPORT:

EXTERN:

GET:

INCLUDE:

INCBIN:

KEEP:

NOFP:

REQUIRE:

REQUIRE8:

PRESERVE8:

RN:

ROUT:

偽指令部分:偽指令不是真正的指令,在匯編編譯器對(duì)源程序進(jìn)行匯編處理時(shí)被替換成對(duì)應(yīng)的ARM或者Thumb指令;

ADR(小范圍的地址讀取偽指令):將基于PC的地址值或者基于寄存器的地址值讀取到寄存器中;

ADR{cond} register, expr

expr是基于PC或者基于寄存器的地址表達(dá)式,取值范圍如下:

地址值不是字對(duì)齊時(shí),取值范圍-255~255;

地址值是字對(duì)齊時(shí),取值范圍-1020~1020;

地址值是16字節(jié)對(duì)齊時(shí),取值范圍更大;

ADRL(中等范圍的地址讀取偽指令):將基于PC的地址值或者基于寄存器的地址值讀取到寄存器中;

ADRL{cond} register, expr

expr是基于PC或者基于寄存器的地址表達(dá)式,取值范圍如下:

地址不是字對(duì)齊時(shí),-64KB~64KB;

地址是字對(duì)齊時(shí),-256KB~256KB;

地址是16字節(jié)對(duì)齊時(shí),取值范圍更大;

LDR:將一個(gè)32位的常數(shù)或者一個(gè)地址值讀取到寄存器中;

LDR{cond} register, ={expr | label-expr}

expr為32位常量;

label-expr為基于PC的地址表達(dá)式或者外部表達(dá)式;

NOP:匯編時(shí)被替換成ARM中的空操作;

實(shí)例程序:

1、

AREA LDR_Code, CODE, READONLY
ENTRY

LDR r0, =src
LDR r1, =dst
MOV r2, r0
MOV r3, r1
MOV r5, #100
LDR r6, =100
LDR r7, =999999




srcDCD 0, 1;, 2, 3, 4, 5, 6, 7, 8, 9
dstDCD 0, 0;, 0, 0, 0, 0, 0, 0, 0, 0


END

反匯編代碼:

$a
LDR_Code
0x00000000: e59f0024 $... LDR r0,0x2c
0x00000004: e59f1024 $... LDR r1,0x30
0x00000008: e1a02000 . .. MOV r2,r0
0x0000000c: e1a03001 .0.. MOV r3,r1
0x00000010: e3a05064 dP.. MOV r5,#0x64
0x00000014: e3a06064 d`.. MOV r6,#0x64
0x00000018: e59f7014 .p.. LDR r7,0x34
src
$d
0x0000001c: 00000000 .... DCD 0
0x00000020: 00000001 .... DCD 1
dst
0x00000024: 00000000 .... DCD 0
0x00000028: 00000000 .... DCD 0
0x0000002c: 0000001c .... DCD 28
0x00000030: 00000024 $... DCD 36
0x00000034: 000f423f ?B.. DCD 999999

(1)為L(zhǎng)DR偽指令生成的代碼,似乎有問(wèn)題,不是基于PC的值,還是有默認(rèn)的規(guī)則?

使用GNU ARM Assembly將上面的代碼重新實(shí)現(xiàn)一次:

.section .text
.global _start
_start:
LDR r0, =src
LDR r1, =dst
LDR r2, =1000
LDR r3, =5555


MOV r4, r2
MOV r5, r3


.section .data
src: .word 0, 0
dst: .word 0, 1

編譯通過(guò)了,不確定代碼有沒(méi)有問(wèn)題,后面再檢查

將上面的代碼使用arm-none-eabi-as編譯不鏈接,然后使用arm-none-eabi-objdump反匯編:

Disassembly of section .text:


00000000 <_start>:
0: e59f0010 ldr r0, [pc, #16] ; 18 <_start+0x18>
4: e59f1010 ldr r1, [pc, #16] ; 1c <_start+0x1c>
8: e3a02ffa mov r2, #1000 ; 0x3e8
c: e59f300c ldr r3, [pc, #12] ; 20 <_start+0x20>
10: e1a04002 mov r4, r2
14: e1a05003 mov r5, r3
18: 00000000 andeq r0, r0, r0
1c: 00000008 andeq r0, r0, r8
20: 000015b3 strheq r1, [r0], -r3

誠(chéng)如文檔中對(duì)LDR的介紹:

LDR r0, =src
LDR r1, =dst
LDR r2, =1000
LDR r3, =5555

這四條命令都進(jìn)行了處理,以LDR r0, =src為例:

0: e59f0010 ldr r0, [pc, #16] ; 18 <_start+0x18>

src的值被存儲(chǔ),ldr指令將[pc, #16]地址中的值加載到寄存器r0中,

ARM處理器中,pc的值為當(dāng)前執(zhí)行的指令的地址值加上8,因此,執(zhí)行該條

指令時(shí),pc的值為8,此時(shí)pc加上16,則為十進(jìn)制的24,十六進(jìn)制的

0x18,但是此時(shí)地址單元0x18中存儲(chǔ)的卻是一條指令:

andeq r0, r0, r0

為什么?

將之前編譯生成的.o文件使用arm-none-eabi-ld進(jìn)行連接,生成可執(zhí)行文件,

然后反匯編,此時(shí)代碼變?yōu)椋?/p>

Disassembly of section .text:


00008000 <_start>:
8000: e59f0010 ldr r0, [pc, #16] ; 8018 <_start+0x18>
8004: e59f1010 ldr r1, [pc, #16] ; 801c <_start+0x1c>
8008: e3a02ffa mov r2, #1000 ; 0x3e8
800c: e59f300c ldr r3, [pc, #12] ; 8020 <_start+0x20>
8010: e1a04002 mov r4, r2
8014: e1a05003 mov r5, r3


8018: 00010024 andeq r0, r1, r4, lsr #32
801c: 0001002c andeq r0, r1, ip, lsr #32
8020: 000015b3 strheq r1, [r0], -r3

此時(shí),src的值應(yīng)該存放在0x8000 + 8 + 16,8和16都是十進(jìn)制的,因此應(yīng)該是0x8018,

但是0x8018地址單元中為:

andeq r0, r1, r4, lsr #32

lsr在上一篇尋址方式中有所介紹,此時(shí)r4中的值通過(guò)上面的指令可知為十進(jìn)制的1000,十六進(jìn)制的0x3E8,

0x3E8的二進(jìn)制:

0000 0000 0000 0000 0000 0011 1110 1000,執(zhí)行l(wèi)sr #32操作,右移32位,則變?yōu)?,

r1中此時(shí)不管是什么值,AND指令執(zhí)行按位取與操作,指令的執(zhí)行結(jié)果自然是0,存放到r0寄存器中?

此處應(yīng)該是個(gè)pool?為什么是指令?

(2)$a、$d分別表示什么意思?

摘錄自:Using asThegnuAssembler的Mapping Symbols章節(jié)

The ARM ELF specification requires that special symbols be inserted into object files to
mark certain features:
$a At the start of a region of code containing ARM instructions.
$t At the start of a region of code containing THUMB instructions.
$d At the start of a region of data.

待補(bǔ)充...



評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉