ARM汇编中的ROM与RAM以及AREA指令

时间:2017-04-13 00:35:03

标签: assembly arm thumb

所以我有一个简单的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。但是在这里,它们位于CODE部分,它是READONLY(因此我假设它在ROM中)在没有AREA指令的部分中。我不确定那里有什么默认值。

DCD在READONLY部分声明,但我仍然可以写信给它。

如果我在空白部分添加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

EQUs和DCD无处不在,AREA指令似乎根本不会影响我如何访问它们。另外,将READONLY添加到AREA DATA指令也没有效果。

1 个答案:

答案 0 :(得分:1)

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

.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

并且在编译传递之前完成搜索并用0x12345678替换ABCD的实例。汇编程序也是如此。与C不同,您可能无法做更多的搜索和替换,汇编程序宏是不同的语法。但它是定义的。

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

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