我确实找到了这个链接:ARM 中分支指令的偏移计算
这对我很有帮助,但也让我感到困惑。我尝试了几种方法来让它与我的偏移一起工作,但失败了。
我想做的是创建一条从 0x52F4D6 到 0x5BF368 的 BL 指令。
在 0x52F4D6 我想写 BL sub_5BF368 但我如何获得正确的十六进制代码(拇指)?
谢谢!
我确实找到了这个链接:ARM 中分支指令的偏移计算
这对我很有帮助,但也让我感到困惑。我尝试了几种方法来让它与我的偏移一起工作,但失败了。
我想做的是创建一条从 0x52F4D6 到 0x5BF368 的 BL 指令。
在 0x52F4D6 我想写 BL sub_5BF368 但我如何获得正确的十六进制代码(拇指)?
谢谢!
您可以从 ARM 手册中获取此信息;例如,从您找到的链接中链接的版本https://ece.uwaterloo.ca/~ece222/ARM/ARM7-TDMI-manual-pt3.pdf。
首先,快速计算5BF358-52F4D6产生8FE82,所以你看到你有超过 12 位,并且需要使用 5.19 中的长分支格式,它将你BL分成两条指令。该部分说“分支偏移量必须考虑到预取操作,这会导致 PC 在当前指令之前 1 个字(4 个字节)”,因此您需要的偏移量来自52F4D6-后面的 4 个字节52F4DA,这意味着偏移量对于说明 - 您要添加的值PC是8FE7E.
指令的第一部分将其部分偏移量左移 12 位,并将其添加到 PC。指令格式是1111HXXXXXXXXXXX二进制的,有H=0, 所以F000+XXXX是十六进制的。在这一步中要添加到 PC 的是8F000,因此该指令的操作码是F0 8F.
第二部分将它的部分偏移左移一位(记住拇指指令对齐到 16 位,所以偏移的最后一位总是 0,所以它不必在十六进制操作码中表示),并且它有H=1,所以操作码是F800+XXXX。您要在此步骤中添加的是E7E. 将其右移一位以获取73f,并将其添加到您的操作码以获取FF 3F。
所以,你的 BL 指令是F08F FF3F.
为了确认这一点,创建一个汇编程序,汇编它,并检查结果:
.thumb
.arch armv7a
.syntax unified
.align 2
.org 0x52F4D6
bl sub_5BF368
.org 0x5BF368
sub_5BF368:
arm-linux-gnueabi-as -o y.o y.s
arm-linux-gnueabi-objdump -s y.o | grep -v "00000000 00000000 00000000 00000000"
.....
52f4d0 00000000 00008ff0 3fff0000 00000000 ........?.......
....
请记住,由于小字节序,单词是字节交换的,您会在F08F FF3F那里找到您的操作码。
编辑:我刚刚修复了第二个 .org 的地址,因为它似乎是为了避免混淆而输入错误。现在我认为它看起来一致:)