ARM汇编和AREA指令中的ROM与RAM



所以我有一个简单的ARM程序集(特别是THUMB)程序正在为TI微控制器编译。我只是对EQU和DCD存储在内存中的位置(RAM与ROM)以及AREA指令与此有何关系感到困惑。我从这个开始:

Y1      EQU     0x23

AREA    |.text|, CODE, READONLY, ALIGN=2
THUMB
X2      DCD     0x23
Y2      EQU     0x23
MOV R0, #0
LDR R1, =X2
STR R0, [R1]
END

我假设由于 EQU 是恒定的,它们进入 ROM。但是在这里,它们位于只读的代码部分(所以我假设它在ROM中)没有AREA指令的部分。我不确定那里的默认值是什么。

DCD是在只读部分中声明的,但我仍然可以写入它。

如果我将DCD添加到空白部分,则会出现错误:Area directive missing。如果我添加 AREA 指令,那么代码如下所示:

AREA    |.data|, DATA
X1      DCD     0x23
Y1      EQU     0x23

AREA    |.text|, CODE, READONLY, ALIGN=2
THUMB
EXPORT  Start
X2      DCD     0x23
Y2      EQU     0x23
Start
MOV R0, #0
LDR R1, =X1
STR R0, [R1]
MOV R0, #0
LDR R1, =X2
STR R0, [R1]
END

EQU 和 DCD 无处不在,AREA 指令似乎根本不影响我访问它们的方式。此外,将 READONLY 添加到 AREA DATA 指令也不起作用。

使用我可以访问的汇编程序,您提出的问题应该在两种汇编语言之间移植,因为许多问题是关于指令集而不是汇编语言的。

.equ X1,0x12345678
.text
.thumb
.globl _start
_start:

ldr r0,=X1
ldr r1,=X2
ldr r2,[r1]
ldr r3,=Y4
ldr r4,=Y3
str r3,[r4]
bl bounce
mov lr,pc
ldr r5,=bounce
bx r5
b .
X2: .word 0xAABBCCDD
.thumb_func
bounce:
bx lr
nop
.data
Y3: .word 0
Y4: .word 0x11223344

组装链接和拆卸。

00001000 <_start>:
1000:   4807        ldr r0, [pc, #28]   ; (1020 <bounce+0x4>)
1002:   4908        ldr r1, [pc, #32]   ; (1024 <bounce+0x8>)
1004:   680a        ldr r2, [r1, #0]
1006:   4b08        ldr r3, [pc, #32]   ; (1028 <bounce+0xc>)
1008:   4c08        ldr r4, [pc, #32]   ; (102c <bounce+0x10>)
100a:   6023        str r3, [r4, #0]
100c:   f000 f806   bl  101c <bounce>
1010:   46fe        mov lr, pc
1012:   4d07        ldr r5, [pc, #28]   ; (1030 <bounce+0x14>)
1014:   4728        bx  r5
1016:   e7fe        b.n 1016 <_start+0x16>
00001018 <X2>:
1018:   aabbccdd    bge feef4394 <X1+0xecbaed1c>
0000101c <bounce>:
101c:   4770        bx  lr
101e:   46c0        nop         ; (mov r8, r8)
1020:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000
1024:   00001018    andeq   r1, r0, r8, lsl r0
1028:   00002004    andeq   r2, r0, r4
102c:   00002000    andeq   r2, r0, r0
1030:   0000101d    andeq   r1, r0, sp, lsl r0
Disassembly of section .data:
00002000 <__data_start>:
2000:   00000000    andeq   r0, r0, r0
00002004 <Y4>:
2004:   11223344            ; <UNDEFINED> instruction: 0x11223344
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0:   00001341    andeq   r1, r0, r1, asr #6
4:   61656100    cmnvs   r5, r0, lsl #2
8:   01006962    tsteq   r0, r2, ror #18
c:   00000009    andeq   r0, r0, r9
10:   01090206    tsteq   r9, r6, lsl #4

所以它采用了 LDR r0,=0x12345678 并将其变成这个

1000:  4807        ldr r0, [pc, #28]   ; (1020 <bounce+0x4>)

而这个

1020:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000

负载(32 位,因为它是 LDR,LDRB 将是 8(填充),LDRH 16 位(填充))将 PC 提前两条指令,将 28 加到该0x1000 + 4 + 28 = 0x1000 + 32 = 0x1000 + 0x20 因此他们在该地址将数据放置在0x12345678。 所有其他=某物也是如此...

不过,我本可以自己做到这一点,而不是依赖伪指令。

.text
.thumb
.globl _start
_start:
ldr r0,xyz
ldr r1,xyz_add
ldr r2,[r1]
b .
xyz: .word 0x12345678
xyz_add: .word xyz

未链接就足够好了

00000000 <_start>:
0:   4801        ldr r0, [pc, #4]    ; (8 <xyz>)
2:   4902        ldr r1, [pc, #8]    ; (c <xyz_add>)
4:   680a        ldr r2, [r1, #0]
6:   e7fe        b.n 6 <_start+0x6>
00000008 <xyz>:
8:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000
0000000c <xyz_add>:
c:   00000008    andeq   r0, r0, r8

因为我把它放在同一个部分,所以我可以直接加载0x12345678我不需要获取地址然后从地址加载基本上是 =0x12345678 伪代码所做的。 但是对于遥远的东西,您仍然可以将数据项作为地址,然后加载该地址,然后从该地址加载(双间接)。

.text
.thumb
.globl _start
_start:
ldr r0,=0x11223344
ldr r1,=5

至少使用一个汇编程序,您可以将 =Something 技巧用于所有内容,并且汇编程序有望在适合的情况下进行优化。

00000000 <_start>:
0:   4800        ldr r0, [pc, #0]    ; (4 <_start+0x4>)
2:   2105        movs    r1, #5
4:   11223344

如果它走另一条路会很好,如果你立即做一个 MOV,它会做负载 PC 相对,如果它不适合,但我认为他们不会这样做。

现在把它翻译成你的汇编语言。 AREA 声明声明链接器稍后定义它们的位置的 .text 和 .data。 一些链接器可以修改代码,而不仅仅是立即偏移,有些链接器有时可以替换整个指令(根据需要蹦蹦跳跳地删除一些链接器插入的代码)。 在这种情况下,链接器将在各部分中的汇编器分配的数据位置中填写事物的地址。

您可以在 .text 和 .data 中包含数据项 .text 数据项是只读的,无论是像表或地址一样,还是代码或部分中其他链接的事物。 链接器必须填写远程地址的内容,因为它们在组装时未解析。

EQU 在历史上是 C 语言中简单定义的汇编语言版本

#define ABCD 0x12345678

在编译通行证之前,搜索 ABCD 的实例并将其替换为 0x12345678。 汇编程序也是如此。 与 C 不同,您可能不能做的不仅仅是搜索和替换,汇编宏是不同的语法。 但它是定义状的。

DCD,DCB等就像GNU汇编程序中的.word,.byte,他们说我想在这里放一些原始数据或在这里为原始数据分配空间,不是指令,而是出于任何原因我想使用它的数据。

人们希望,如果汇编程序有一个 READONLY 指令,它尊重它,如果不是,那会打扰我。 但与此同时,使用良好的名称.text,.data可能胜过这一点。

最新更新