Gcc 获取THUMB程序集上寄存器的标签地址-Armv5

Gcc 获取THUMB程序集上寄存器的标签地址-Armv5,gcc,assembly,arm,reverse-engineering,thumb,Gcc,Assembly,Arm,Reverse Engineering,Thumb,我正在尝试获取thumb assembly中标签的地址,但遇到了一些问题 我已经读过了,但这对我没有帮助,我会解释原因 我正在用Thumb汇编编写一个简单的程序,不幸的是我不能使用Thumb2 让我们考虑这个代码: 我正在使用ARMLinuxGnueAbi工具链来组装它 我的微控制器没有MMU,所以内存地址是静态的,没有虚拟页面等 我正在尝试做的事情是在这里使R0的值为0x8,这样我就可以访问如下三个单词: 但这在LDR中是不可能的,因为单词中的值不可能适合MOV命令。汇编程序的文档说明,如果该

我正在尝试获取thumb assembly中标签的地址,但遇到了一些问题

我已经读过了,但这对我没有帮助,我会解释原因

我正在用Thumb汇编编写一个简单的程序,不幸的是我不能使用Thumb2

让我们考虑这个代码:

我正在使用ARMLinuxGnueAbi工具链来组装它

我的微控制器没有MMU,所以内存地址是静态的,没有虚拟页面等

我正在尝试做的事情是在这里使R0的值为0x8,这样我就可以访问如下三个单词:

但这在LDR中是不可能的,因为单词中的值不可能适合MOV命令。汇编程序的文档说明,如果该值不能放入MOV命令中,那么它将把该值放入文本池中

所以我的问题是,如果地址的内容不能放入MOV命令中,那么在Thumb assembly中是否可以获得标签的实际地址

从这个开始

.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
因此,该工具不会将其转化为池中的负载

对于你想做的事,我认为pc相对add是你能得到的最好的。您可以尝试其他工具链,因为所有这些都是语言,特定于工具链的汇编语言是由汇编程序定义的,而不是由目标程序定义的,并且对于具有汇编程序的每个工具链,语言中可能存在差异。随着gnu内部时间的推移,链接器和汇编程序的工作方式发生了变化,链接器修补了它以前不使用的东西

当然,您可以进入链接器并向其添加代码以执行此优化,问题很可能是,在链接时,链接器正在查找池中的地址,这样做很容易,不必更改指令,汇编器必须为链接器留下信息,说明这不仅仅是一个用地址填充内存位置的东西,或者修改gas以允许adr工作,然后如果链接器无法在指令内解析它,则链接器会出错退出。”

或者你可以硬编码你想要的并维护它。不确定为什么adr解决方案不充分

mov r0,8


是有效的thumb指令。

是的,您让工具将其放在附近的池中,然后它将其放在那里。gnu汇编程序将ldr转换为pc相对负载。它不是为您这样做的吗?它确实适用于文本池,但出于好奇,我的问题主要是,是否可以实际获取实际数据的地址,而不是文本池实例的地址。与固定长度指令集中的任何立即数一样,您受限于有效位的数量。arm、mips、risc-v等。thumb和16位mips以及16位risc-v指令会进一步限制您,因此通常不会。它不会适用于所有情况。这种愿望的另一个问题是地址是由链接时间决定的,而不是在汇编期间,因此可以说他们可以为pc相对负载编码,然后放弃该常量,并在链接时间将其设置为pc相对添加。但事实并非如此,而且可能这是一种语言,目标的每种汇编语言都是特定于该工具的。如果您在gnu assembler for arm上使用ldr,那么如果它当时知道值并且适合,它将成为mov。人们希望它也能将ldr转换为与adr伪指令等效的指令,但事实并非如此。一个实验是使用adr和一个不合适的立即数,看看汇编程序是否失败,或者将其转换为ldr plus add或其他什么。注意,答案在上一篇文章的答案中,所以从技术上讲,这是一个重复。我想我明白了问题所在,我明天会试试,我会发送更新:无论如何,非常感谢你的回答!你是对的,我很困惑,因为adr命令不在ARMV5手册中,我也不是很聪明地认为它不受ARMV5支持。然后你说了,我意识到这是一条伪指令,汇编程序会把它转换成体系结构支持的东西。非常感谢您的时间,我知道这似乎是一个有点愚蠢的问题,但它帮助我在这个问题上获得了更好的直觉。当有疑问时,试一下,最坏的情况是,汇编程序不认识它…这就是我所做的,我想是幸运的。
.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
.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