将标签地址获取到 THUMB 程序集上的寄存器 - Armv5
Getting an label address to a register on THUMB assembly - Armv5
我正在尝试获取拇指组件中标签的地址,但遇到了一些问题。
我已经读过 this post 但这对我没有帮助,我会解释原因。
我正在用 Thumb 程序集编写一个简单的程序(不幸的是我不能使用 Thumb2)。
让我们考虑这段代码:
.arch armv5te
.syntax unified
.text
.thumb
.thumb_func
thumbnow:
0x0 PUSH {LR}
0x2 LDR R0, =loadValues
0x4 POP {PC}
.align
loadValues:
0x8 .word 0xdeadbee1
0xC .word 0xdeadbee2
0x10 .word 0xdeadbee3
我正在使用 arm-linux-gnueabi 工具链assemble。
我的微控制器没有 MMU,所以内存地址是静态的,没有虚拟页面等。
我想做的是让 R0 在这里具有 0x8 的值,这样我就可以像这样访问三个词:
LDR R1, [R0]
LDR R2, [R0,#4]
LDR R3, [R0,#8]
这对于 LDR 是不可能的,因为字中的值不可能适合 MOV 命令。 assembler 的文档指出,如果该值不适合 MOV 命令,那么它将将该值放入文字池中。
所以我的问题是,如果地址的内容不能放在MOV命令中,是否有可能在Thumb汇编中获取标签的实际地址?
从此开始
.thumb
ldr r0,=hello
adr r0,hello
nop
nop
nop
nop
hello:
.word 0,1,2,3
未link编辑
00000000 <hello-0xc>:
0: 4806 ldr r0, [pc, #24] ; (1c <hello+0x10>)
2: a002 add r0, pc, #8 ; (adr r0, c <hello>)
4: 46c0 nop ; (mov r8, r8)
6: 46c0 nop ; (mov r8, r8)
8: 46c0 nop ; (mov r8, r8)
a: 46c0 nop ; (mov r8, r8)
0000000c <hello>:
c: 00000000 andeq r0, r0, r0
10: 00000001 andeq r0, r0, r1
14: 00000002 andeq r0, r0, r2
18: 00000003 andeq r0, r0, r3
1c: 0000000c andeq r0, r0, r12
linked
00001000 <hello-0xc>:
1000: 4806 ldr r0, [pc, #24] ; (101c <hello+0x10>)
1002: a002 add r0, pc, #8 ; (adr r0, 100c <hello>)
1004: 46c0 nop ; (mov r8, r8)
1006: 46c0 nop ; (mov r8, r8)
1008: 46c0 nop ; (mov r8, r8)
100a: 46c0 nop ; (mov r8, r8)
0000100c <hello>:
100c: 00000000 andeq r0, r0, r0
1010: 00000001 andeq r0, r0, r1
1014: 00000002 andeq r0, r0, r2
1018: 00000003 andeq r0, r0, r3
101c: 0000100c andeq r1, r0, r12
两种方式 r0 都会 return 数据开始的地址,然后您可以从该地址偏移到来自调用者或任何地方的数据。
编辑
.thumb
adr r0,hello
nop
nop
nop
arm-none-eabi-as so.s -o so.o
so.s: Assembler messages:
so.s:2: Error: address calculation needs a strongly defined nearby symbol
因此该工具不会为您将其转换为池中的负载。
对于你想做的事情,我认为 pc 相对添加 (adr) 是你能得到的最好的。您可以尝试其他工具链,因为所有这些都是特定于语言和工具链的(汇编语言是由汇编器而不是目标定义的,并且对于每个工具链(带有汇编器),语言可能有所不同)。随着时间的推移,在 gnu 中,linker 和汇编程序如何一起工作发生了变化,linker 修补了它不习惯的东西。
您当然可以进入 linker 并向其添加代码以执行此优化,问题很可能是 link 时间 linker 正在寻找要解析池中的一个地址,这很容易做到,它不必更改指令,汇编器必须为 linker 留下信息,这不仅仅是填充这个内存位置地址问题,要么你修改 gas 以允许 adr 工作,然后如果 linker 无法在指令中解决它,那么 linker 会因错误而退出。'
或者您可以对您想要的内容进行硬编码并进行维护。我不确定为什么 adr 解决方案不够用。
mov r0,#8
是有效的拇指指令。
我正在尝试获取拇指组件中标签的地址,但遇到了一些问题。
我已经读过 this post 但这对我没有帮助,我会解释原因。
我正在用 Thumb 程序集编写一个简单的程序(不幸的是我不能使用 Thumb2)。
让我们考虑这段代码:
.arch armv5te .syntax unified .text .thumb .thumb_func thumbnow: 0x0 PUSH {LR} 0x2 LDR R0, =loadValues 0x4 POP {PC} .align loadValues: 0x8 .word 0xdeadbee1 0xC .word 0xdeadbee2 0x10 .word 0xdeadbee3
我正在使用 arm-linux-gnueabi 工具链assemble。
我的微控制器没有 MMU,所以内存地址是静态的,没有虚拟页面等。
我想做的是让 R0 在这里具有 0x8 的值,这样我就可以像这样访问三个词:
LDR R1, [R0] LDR R2, [R0,#4] LDR R3, [R0,#8]
这对于 LDR 是不可能的,因为字中的值不可能适合 MOV 命令。 assembler 的文档指出,如果该值不适合 MOV 命令,那么它将将该值放入文字池中。
所以我的问题是,如果地址的内容不能放在MOV命令中,是否有可能在Thumb汇编中获取标签的实际地址?
从此开始
.thumb
ldr r0,=hello
adr r0,hello
nop
nop
nop
nop
hello:
.word 0,1,2,3
未link编辑
00000000 <hello-0xc>:
0: 4806 ldr r0, [pc, #24] ; (1c <hello+0x10>)
2: a002 add r0, pc, #8 ; (adr r0, c <hello>)
4: 46c0 nop ; (mov r8, r8)
6: 46c0 nop ; (mov r8, r8)
8: 46c0 nop ; (mov r8, r8)
a: 46c0 nop ; (mov r8, r8)
0000000c <hello>:
c: 00000000 andeq r0, r0, r0
10: 00000001 andeq r0, r0, r1
14: 00000002 andeq r0, r0, r2
18: 00000003 andeq r0, r0, r3
1c: 0000000c andeq r0, r0, r12
linked
00001000 <hello-0xc>:
1000: 4806 ldr r0, [pc, #24] ; (101c <hello+0x10>)
1002: a002 add r0, pc, #8 ; (adr r0, 100c <hello>)
1004: 46c0 nop ; (mov r8, r8)
1006: 46c0 nop ; (mov r8, r8)
1008: 46c0 nop ; (mov r8, r8)
100a: 46c0 nop ; (mov r8, r8)
0000100c <hello>:
100c: 00000000 andeq r0, r0, r0
1010: 00000001 andeq r0, r0, r1
1014: 00000002 andeq r0, r0, r2
1018: 00000003 andeq r0, r0, r3
101c: 0000100c andeq r1, r0, r12
两种方式 r0 都会 return 数据开始的地址,然后您可以从该地址偏移到来自调用者或任何地方的数据。
编辑
.thumb
adr r0,hello
nop
nop
nop
arm-none-eabi-as so.s -o so.o
so.s: Assembler messages:
so.s:2: Error: address calculation needs a strongly defined nearby symbol
因此该工具不会为您将其转换为池中的负载。
对于你想做的事情,我认为 pc 相对添加 (adr) 是你能得到的最好的。您可以尝试其他工具链,因为所有这些都是特定于语言和工具链的(汇编语言是由汇编器而不是目标定义的,并且对于每个工具链(带有汇编器),语言可能有所不同)。随着时间的推移,在 gnu 中,linker 和汇编程序如何一起工作发生了变化,linker 修补了它不习惯的东西。
您当然可以进入 linker 并向其添加代码以执行此优化,问题很可能是 link 时间 linker 正在寻找要解析池中的一个地址,这很容易做到,它不必更改指令,汇编器必须为 linker 留下信息,这不仅仅是填充这个内存位置地址问题,要么你修改 gas 以允许 adr 工作,然后如果 linker 无法在指令中解决它,那么 linker 会因错误而退出。'
或者您可以对您想要的内容进行硬编码并进行维护。我不确定为什么 adr 解决方案不够用。
mov r0,#8
是有效的拇指指令。