.word 在这里使用
ldr r0,hello
nop
nop
nop
hello: .word 0x12345678
类似于
unsigned int word = 0x12345678
你好:是一个标签。word与它无关。只是意味着我现在想为地址使用标签,可以在那里放置代码或数据或其他任何东西。就像 C 中的 unsigned int 一样,您在程序中分配了一些空间。
.equ 虽然就像定义你没有分配空间,但你只是为那个字符串定义了一些替换。
arm-none-eabi-as so.s -o so.o
arm-none-eabi-objdump -D so.o
...
00000000 <hello-0x10>:
0: e59f0008 ldr r0, [pc, #8] ; 10 <hello>
4: e1a00000 nop ; (mov r0, r0)
8: e1a00000 nop ; (mov r0, r0)
c: e1a00000 nop ; (mov r0, r0)
00000010 <hello>:
10: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
如果我添加这个
.equ JELLO, 0x22
ldr r0,hello
nop
nop
nop
hello: .word 0x12345678
没有变化,如果我这样做
.equ JELLO, 0x12345678
ldr r0,JELLO
.equ 是一个类似于替换的定义。
ldr r0,0x12345678
so.s: Assembler messages:
so.s:2: Error: internal_relocation (type: OFFSET_IMM) not fixed up
现在如果我们想要 r0 中的 VALUE,那么这是一个语法问题。
mov r0,#0x12345678
我们在 ARM 中无法做到这一点,指令是 16 位或 32 位,仅此而已,因此您不能拥有 32 位立即数和操作码和寄存器等 32 位。所以必须给出一些东西,取决于指令集和变化的立即数在几到可能 11 或 13 位之间,正常的 arm mov 指令全尺寸 arm 指令,如 9 个有效位。
so.s: Assembler messages:
so.s:3: Error: invalid constant (12345678) after fixup
有趣的是,诀窍是返回加载并询问汇编程序,我想要标签的地址而不是标签上的东西。
ldr r0,=hello
nop
nop
nop
hello: .word 0x12345678
.word 0,1,2,3
汇编器为我们分配了一个字,它可以找到一个空格
00000000 <hello-0x10>:
0: e59f001c ldr r0, [pc, #28] ; 24 <hello+0x14>
4: e1a00000 nop ; (mov r0, r0)
8: e1a00000 nop ; (mov r0, r0)
c: e1a00000 nop ; (mov r0, r0)
00000010 <hello>:
10: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
14: 00000000 andeq r0, r0, r0
18: 00000001 andeq r0, r0, r1
1c: 00000002 andeq r0, r0, r2
20: 00000003 andeq r0, r0, r3
24: 00000010 andeq r0, r0, r0, lsl r0
请注意,它没有将地址 0x10 处的东西加载到寄存器中,而是将地址 0x24 处的东西加载到它为我们添加的位置,并且在该位置它向 hello 提供地址 0x10,因此 r0 将获得 0x10 而不是0x12345678 通过添加等号。有点像在 C 中删除一维指针上的星号,你得到的是指针的地址,而不是指针指向的东西。
所以知道这个 ldr rx,=something 意味着我想要那个标签的地址,如果我们只是放一个地址而不是代表地址的标签呢?
ldr r0,=0x87654321
nop
nop
nop
hello: .word 0x12345678
.word 0,1,2,3
它恰好起作用
0000000 <hello-0x10>:
0: e59f001c ldr r0, [pc, #28] ; 24 <hello+0x14>
4: e1a00000 nop ; (mov r0, r0)
8: e1a00000 nop ; (mov r0, r0)
c: e1a00000 nop ; (mov r0, r0)
00000010 <hello>:
10: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
14: 00000000 andeq r0, r0, r0
18: 00000001 andeq r0, r0, r1
1c: 00000002 andeq r0, r0, r2
20: 00000003 andeq r0, r0, r3
24: 87654321 strbhi r4, [r5, -r1, lsr #6]!
因此,这并不能证明您可以在任何您想要的基于 gnu 汇编器的指令集中盲目地将 .word 替换为 .equ,但是由于运气不佳,您几乎可以通过修复语法来实现
.equ JELLO,0x12345678
ldr r0,=JELLO
nop
nop
nop
你去吧
00000000 <.text>:
0: e59f0008 ldr r0, [pc, #8] ; 10 <JELLO-0x12345668>
4: e1a00000 nop ; (mov r0, r0)
8: e1a00000 nop ; (mov r0, r0)
c: e1a00000 nop ; (mov r0, r0)
10: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
通常,对于任何/其他指令集 .word 到 .equ 的负载,您需要更改为 mov
.equ JELLO,0x12
ldr r0,hello
mov r0,#JELLO
nop
nop
nop
hello:
.word 0x12
00000000 <hello-0x14>:
0: e59f000c ldr r0, [pc, #12] ; 14 <hello>
4: e3a00012 mov r0, #18
8: e1a00000 nop ; (mov r0, r0)
c: e1a00000 nop ; (mov r0, r0)
10: e1a00000 nop ; (mov r0, r0)
00000014 <hello>:
14: 00000012 andeq r0, r0, r2, lsl r0
使用 x86 中的任何语法(mov、move 等你好语法也许))
注意我使用的是上面的遗留 gnu 汇编器语法,所以使用它
.equ JELLO,0x12
mov r0,JELLO
给
so.s: Assembler messages:
so.s:4: Error: immediate expression requires a # prefix -- `mov r0,JELLO'
但是如果我们使用统一的语法,我想它不再关心井号了。
.syntax unified
.equ JELLO,0x12
mov r0,JELLO
mov r0,#JELLO
00000000 <.text>:
0: e3a00012 mov r0, #18
4: e3a00012 mov r0, #18
不是粉丝,应该让它更容易(更懒惰),只是让它变得更糟......这就是为什么我很少使用它,除非我必须......YMMV。