我试图获取拇指装配中标签的地址,但遇到了一些麻烦。
我已经读过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工具链进行组装。
我的微控制器没有MMU,因此内存地址是静态的,没有虚拟页面等。
我想做的是在这里使R0的值为0x8,这样我就可以访问这三个词:
LDR R1, [R0] LDR R2, [R0,#4] LDR R3, [R0,#8]
尽管对于LDR来说这是不可能的,因为单词中的值不可能适合MOV命令。汇编程序的文档指出,如果该值不能容纳在MOV命令中,则它将把该值放入文字池中。
所以我的问题是,如果该地址的内容不能容纳在MOV命令中,那么在Thumb汇编中是否可以获取标签的实际地址?
答案 0 :(得分:1)
从此开始
.thumb
ldr r0,=hello
adr r0,hello
nop
nop
nop
nop
hello:
.word 0,1,2,3
给予此取消链接
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
链接
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两种方式都将地址返回到数据的开头,然后您可以从该地址将其偏移到调用方或任何地方的数据中。
编辑
.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中,随着时间的推移,链接程序和汇编程序的协同工作方式发生了变化,链接程序修补了以前不曾使用过的内容。
您当然可以进入链接器并向其添加代码以执行此优化,问题很可能是由于链接时间,链接器正在寻找解析池中的地址,这很容易做到必须更改指令,汇编器将不得不为链接器保留信息,这不仅是用地址来填充该存储位置,或者您修改gas以允许adr起作用,然后如果链接器无法在其中解决它指令,然后链接器会因出错而失败。'
或者您也可以硬编码所需的内容并对其进行维护。不确定为什么adr解决方案不够充分。
mov r0,#8
是有效的拇指指令。