Assembly ARM组件中的ROM vs RAM和AREA指令

Assembly ARM组件中的ROM vs RAM和AREA指令,assembly,arm,thumb,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,

所以我有一个简单的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中),并且在没有区域指令的部分。我不确定默认值是多少

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

如果将DCD添加到空部分,则会出现错误:
区域指令缺失
。如果添加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无处不在,区域指令似乎根本不会影响我如何访问它们。另外,将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
加载(32位,因为它是一个ldr,ldrb将是8位(填充),ldrh 16位(填充))接收前面两条指令的pc,向0x1000+4+28=0x1000+32=0x1000+0x20添加28,因此他们将数据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
至少有一个汇编器,你可以在任何事情上使用=something技巧,如果适合的话,汇编器将有望进行优化

00000000 <_start>:
   0:   4800        ldr r0, [pc, #0]    ; (4 <_start+0x4>)
   2:   2105        movs    r1, #5
   4:   11223344
在编译之前,执行pass以搜索ABCD实例并将其替换为0x12345678。汇编程序也是如此。与C语言不同的是,你可能不能做的不仅仅是搜索和替换,汇编宏是不同的语法。但它是这样定义的

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


有人会希望,如果汇编程序有一个只读指令,它会遵守它,如果它不是,这会困扰我。但与此同时,常用的names.text.data可能会胜过它。

EQU指令不分配任何内存,因此它不会“去”任何地方。它只是给一个符号赋值。DCD指令在当前部分为一个或多个32位字分配内存,用给定的值初始化这些字,然后分配分配给符号的第一个字的地址。AREA指令对ROM或RAM中的任何内容都没有直接影响。这取决于链接器如何配置为将节映射到ROM或RAM。如果您写入只读部分,汇编程序不会给出错误,CPU可能会忽略写入ROM的任何错误。汇编语言是特定于汇编程序的,您正在使用的软件。你在这里使用什么汇编程序/软件?ARM不是一个充分的答案,因为它不是一个软件程序,而是一家制造许多cpu内核的公司。正如前面所述,EQU就像C中的定义一样,它没有存储空间,只是程序中的ascii替代解决方案,在组装之前进行搜索和替换。DCD确实分配了空间,但它在节中,您可以并且需要.data和.text中的数据项。例如,在.text中,您需要无法作为立即数加载的地址。如您所演示的(ldr r1,=x2),它在.text空间中为该地址分配一个32位数据项。链接决定了.text和.data的位置,如果你想的话,它们可能都在ram中…@old_timer我在用Keil uVision。另外,如果eq只是程序中的一个替换,那么为什么我可以编写
LDR R0,=someeqlabel
?它用什么来代替标签?因为它是32位的,所以它不能放入整个立即值,而且LDR也不接受任何立即值。使用其他汇编程序,您完全可以使用LDR r0,=0x12345678。你认为标签是什么?一个地址,一个32位地址,ldr r0,=someaddress,就是说当你知道地址是什么时,我想要它在寄存器中,所以给我分配一个位置,用一个pc相对加载替换它。如果在搜索和替换之后,文本值不适合指令,它会执行pc相对加载,对吗(如您的示例中的
ldr r0,=0x11223344
)?当然是gnu汇编程序。我不知道你正在使用的汇编语言……只要试一下汇编和反汇编,看看它能做什么。或者换一种方式,做一个mov r0,#某物和等于一个简单而不简单的常数,看看。注意ARM即时编码很容易让你的头脑像8或9个非零位那样at可以以两位为单位进行移位/旋转,比如0xAB000000或0xB000000A等等。thumb立即编码很难让人理解,很明显他们可以处理1或3这样的数字,但其他数字你必须去看。是的,我看了反汇编,看起来大的EQU值(比如32位值)是DCD到一个内存位置,然后使用PC相对寻址来获取它。
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
.text
.thumb

.globl _start
_start:

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