arm - 解码ARM BL指令

标签 arm disassembly opcode thumb

我刚刚开始在我的 Nucleo STM32F303RE 上使用 ARM 架构,我正在尝试了解指令的编码方式。

我已经运行了一个简单的 LED 闪烁程序,前几个反汇编的应用指令是:

08000188:   push    {lr}
0800018a:   sub     sp, #12
235         __initialize_hardware_early ();
0800018c:   bl      0x80005b8 <__initialize_hardware_early>

这些指令在 hex 文件中解析为以下内容(在 Eclipse 中显示很奇怪——每个 32 位字都按 MSB 顺序排列,但 Eclipse 似乎不知道它……但那是另一个主题):

address 0x08000188:  B083B500 FA14F000

使用 ARM 架构引用手册,我已经确认了前 2 条指令,push (0xB500) 和 sub (0xB083)。但是我无法理解“bl”指令。

十六进制指令是 0xFA14F000。引用手册说它是这样分解的:

31.28   27 26 25 24   23............0
cond     1  0  1  L   signed_immed_24

第一个“F”(0xF......)是有道理的:所有条件都已设置(始终)。

“A”没有意义,因为应该设置 L 位 (1011)。不应该是0xFB……吗?

而且 signed_immed_24 也没有意义。引用手册说:

- start with 0x14F000
- sign extend to 30 bits (signed 2's-complement), giving 0x0014F000
- shift left to form 32-bit value, giving 0x0053C000
- add to the PC, which is the current instruction + 8, giving 0x0800018c + 8 + 0x0053C000, or 0x0853C194.

所以我得到一个分支地址 0x0853C194,但反汇编显示 0x080005B8。

我错过了什么?

谢谢! -埃里克

最佳答案

bl 是两条独立的 16 位指令。 armv5(及更早版本)ARM ARM 在记录它们方面做得更好。

111HHoffset11

来自 ARM ARM

The first Thumb instruction has H == 10 and supplies the high part of the branch offset. This instruction sets up for the subroutine call and is shared between the BL and BLX forms.

The second Thumb instruction has H == 11 (for BL) or H == 01 (for BLX). It supplies the low part of the branch offset and causes the subroutine call to take place.

0xFA14 0xF000

0xF000 是第一条指令上偏移量为零 0xFA14是第二条指令偏移量是0x214

如果从 0x0800018c 开始,则为 0x0800018C + 4 + (0x0000214<<1) = 0x080005B8。 4是当前PC的两条指令头。偏移量是以(16 位)指令为单位。

我想 armv7-m ARM ARM 也涵盖了它,但更难阅读,而且显然添加了功能。但它们不会影响您使用此分支链接。

ARMv5 ARM ARM 在描述发生的事情方面也做得更好。你当然可以把这两个单独的指令分开

.byte 0x00,0xF0
nop
nop
nop
nop
nop
.byte 0x14,0xFA

它会分支到相同的偏移量(相对于第二条指令)。也许在某些核心中打破了它,但我知道在某些核心中(在 armv5 之后)它是有效的。

关于arm - 解码ARM BL指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42079705/

相关文章:

c - 为 FSMC LCD 编写非阻塞代码

php - 如何将PHP编译成opcode并在生产环境运行?

c++ - 将十六进制代码格式化为 asm 代码

c - 了解stm8s反汇编中的功能?

python - 如何在 dis.dis 之后获取 LOAD_CLASSDEREF 指令?

python - 使用 Perl 的 B::Concise 之类的东西转储 Python opttree?

c - 优化用于模式填充数组的嵌套循环,以帮助编译器生成高效的 ARM 程序集?

android - armeabi 和 armeabi-v7a 文件夹

c - gcc 中的 arm 内联汇编

dos - x86分割、DOS、MZ文件格式、反汇编