ARM 程序集中的 ROM 与 RAM 和 AREA 指令
ROM vs RAM in ARM assembly and the AREA directive
所以我有一个简单的 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)and 在没有 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
EQU 和 DCD 无处不在,AREA 指令似乎根本不影响我访问它们的方式。此外,将 READONLY 添加到 AREA DATA 指令也没有任何效果。
使用我可以访问的 assembler,你问的问题应该在两种汇编语言之间进行转换,因为许多问题是关于指令集而不是汇编语言的。
.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
assemble link 和 disassemble.
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。所有其他 =somethings...
也一样
虽然我可以自己完成,而不是依赖于伪指令。
.text
.thumb
.globl _start
_start:
ldr r0,xyz
ldr r1,xyz_add
ldr r2,[r1]
b .
xyz: .word 0x12345678
xyz_add: .word xyz
unlinked 就足够了
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
至少有一个 assembler 你可以对所有东西使用 =something 技巧并且 assembler 如果合适的话有望优化。
00000000 <_start>:
0: 4800 ldr r0, [pc, #0] ; (4 <_start+0x4>)
2: 2105 movs r1, #5
4: 11223344
如果它走另一条路会很好,如果你立即执行 mov 它会加载 pc relative 如果它不合适,但我认为他们不会那样做。
现在将其翻译成您的汇编语言。 AREA 声明声明 .text 和 .data,linker 稍后定义它们的位置。有些 link 用户可以修改代码,而不仅仅是立即偏移量,有些用户有时可以替换整个指令(根据需要跳出一些 link 用户插入的代码)。在这种情况下,linker 将在 assembler 部分中分配的数据位置中填写事物的地址。
您可以在 .text 和 .data 中拥有数据项。.text 数据项是只读的东西,它是常量,例如表或其他 linked 代码或部分中的东西的地址。 linker 必须填写远程地址的东西,因为它们在 assemble 时没有被解析。
EQU 在历史上是 C 中简单定义的汇编语言版本
#define ABCD 0x12345678
并且在编译之前完成一个过程以搜索 ABCD 的实例并将其替换为 0x12345678。 assembler 也是如此。与 C 不同,您可能无法做的不仅仅是搜索和替换,assembler 宏是不同的语法。但它是类似定义的。
DCD、DCB 等就像 gnu assembler 中的 .word、.byte,他们说我想在这里放一些原始数据或在这里为原始数据分配 space,而不是指令但是无论出于何种原因我都想使用数据。
人们会希望,如果 assembler 有一个 READONLY 指令,它会尊重它,如果不是,那会打扰我。但与此同时,使用得当的名称 .text、.data 可能胜过它。
所以我有一个简单的 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)and 在没有 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
EQU 和 DCD 无处不在,AREA 指令似乎根本不影响我访问它们的方式。此外,将 READONLY 添加到 AREA DATA 指令也没有任何效果。
使用我可以访问的 assembler,你问的问题应该在两种汇编语言之间进行转换,因为许多问题是关于指令集而不是汇编语言的。
.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
assemble link 和 disassemble.
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。所有其他 =somethings...
也一样虽然我可以自己完成,而不是依赖于伪指令。
.text
.thumb
.globl _start
_start:
ldr r0,xyz
ldr r1,xyz_add
ldr r2,[r1]
b .
xyz: .word 0x12345678
xyz_add: .word xyz
unlinked 就足够了
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
至少有一个 assembler 你可以对所有东西使用 =something 技巧并且 assembler 如果合适的话有望优化。
00000000 <_start>:
0: 4800 ldr r0, [pc, #0] ; (4 <_start+0x4>)
2: 2105 movs r1, #5
4: 11223344
如果它走另一条路会很好,如果你立即执行 mov 它会加载 pc relative 如果它不合适,但我认为他们不会那样做。
现在将其翻译成您的汇编语言。 AREA 声明声明 .text 和 .data,linker 稍后定义它们的位置。有些 link 用户可以修改代码,而不仅仅是立即偏移量,有些用户有时可以替换整个指令(根据需要跳出一些 link 用户插入的代码)。在这种情况下,linker 将在 assembler 部分中分配的数据位置中填写事物的地址。
您可以在 .text 和 .data 中拥有数据项。.text 数据项是只读的东西,它是常量,例如表或其他 linked 代码或部分中的东西的地址。 linker 必须填写远程地址的东西,因为它们在 assemble 时没有被解析。
EQU 在历史上是 C 中简单定义的汇编语言版本
#define ABCD 0x12345678
并且在编译之前完成一个过程以搜索 ABCD 的实例并将其替换为 0x12345678。 assembler 也是如此。与 C 不同,您可能无法做的不仅仅是搜索和替换,assembler 宏是不同的语法。但它是类似定义的。
DCD、DCB 等就像 gnu assembler 中的 .word、.byte,他们说我想在这里放一些原始数据或在这里为原始数据分配 space,而不是指令但是无论出于何种原因我都想使用数据。
人们会希望,如果 assembler 有一个 READONLY 指令,它会尊重它,如果不是,那会打扰我。但与此同时,使用得当的名称 .text、.data 可能胜过它。