ARM汇编中的函数地址有一个字节的偏移量?

cha*_*ink 3 assembly arm thumb

例如,我有以下汇编代码objdump。的地址f()080001d4。但printf("%x", f)输出080001d5. 并且f()可以通过(*((int (*)())080001d5))()但是完成(*((int (*)())080001d4))()

为什么函数地址有一个字节的偏移量?

080001d4 <f>:
 80001d4:   2000        movs    r0, #0
 80001d6:   4770        bx  lr
Run Code Online (Sandbox Code Playgroud)

sh1*_*sh1 6

ARM 有两种指令模式,地址的最低有效位用于指示给定函数使用哪种模式。Thumb 模式的奇数地址,ARM 模式的偶数地址。

即使您使用-marm开关重新编译它,地址也会是。

[1] 中的第 A4.1.1 节“在 Thumb 状态和 ARM 状态之间切换”陈述如下:

处于 Thumb 状态的处理器可以通过执行以下任一指令进入 ARM 状态: BX 、 BLX 或加载 PC 的 LDR 或 LDM。

....

目标指令集要么直接在指令中编码(对于 BLX 的立即偏移版本),要么保存为互通地址的 bit[0]。


[1] ARM® 架构参考手册:ARMv7-A 和 ARMv7-R 版。ARM,2014 年。DDI 0406C.c。[在线的]。可用:http : //infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c/index.html。[2019 年 8 月 26 日访问]。