如何解决为什么 ARM 汇编语言中的 B 25 或 BEQ 25 表示“转到 PC + 8 + 100”
我是初学者,我正在学习 32 位 ARM,作为我的计算机组织课程的一部分。 B 25
或 BEQ 25
的含义表示为 go-to PC + 8 + 100
。我明白 100
是什么意思。它是偏移量,因为 ARM 是字节寻址的,我们需要将程序计数器增加 25*4
。但这 +8
是什么意思?有人可以帮我解决这个问题吗?
解决方法
可能出于真正的管道原因,但今天为了反向兼容性,PC 是“领先两个”。前面两条指令,用于 4+4 或 8 字节的全尺寸指令。想想获取、解码、执行,到你要执行的时候,pc 已经提前了两个。
汇编语言特定于汇编器而不是目标。 B 25 是该分支指令上的一个奇怪的操作数,但根据您的问题,假设是指令中的立即编码,即以字为单位。目标地址将是 PC(来自 B 25 指令!!!)加 25*4 加 8。25*4 是因为每个字 4 个字节。所以目的地址是指令的PC加100加8。
Disassembly of section .text:
00000000 <skip-0x24>:
0: e1a00000 nop ; (mov r0,r0)
4: e1a00000 nop ; (mov r0,r0)
8: e1a00000 nop ; (mov r0,r0)
c: e1a00000 nop ; (mov r0,r0)
10: ea000003 b 24 <skip>
14: e1a00000 nop ; (mov r0,r0)
18: e1a00000 nop ; (mov r0,r0)
1c: e1a00000 nop ; (mov r0,r0)
20: e1a00000 nop ; (mov r0,r0)
00000024 <skip>:
24: eafffffe b 24 <skip>
这里的编码:
10: ea000003 b 24 <skip>
显示一个 3 作为立即数,指令的地址是 0x10 所以
0x10 + (3*4) + 8 = 0x10+12+8= 0x10+20 = 0x10+0x14 = 0x24
这个有一个负数编码 0xFFFFFFFE 乘以 8 是 0xFFFFFF8
24: eafffffe b 24 <skip>
所以 0x24 + 0xFFFFFFF8 + 8 = 0x24
请注意,反汇编中的 b 24 表示分支到地址 0x24,而不是像您的问题所暗示的立即数那样的 25。
对于拇指模式,他们也提前了两个,每条指令 16 位或两个字节,2+2 前 4 个字节。
Disassembly of section .text:
00000000 <skip-0x12>:
0: 46c0 nop ; (mov r8,r8)
2: 46c0 nop ; (mov r8,r8)
4: 46c0 nop ; (mov r8,r8)
6: 46c0 nop ; (mov r8,r8)
8: e003 b.n 12 <skip>
a: 46c0 nop ; (mov r8,r8)
c: 46c0 nop ; (mov r8,r8)
e: 46c0 nop ; (mov r8,r8)
10: 46c0 nop ; (mov r8,r8)
00000012 <skip>:
12: e7fe b.n 12 <skip>
所以对于这个(每条指令两个字节,所以 3 * 2)
8: e003 b.n 12 <skip>
0x08 + (0x3
其他指令集可能会在执行期间将 pc 伪造为指令的地址,或者您经常看到它指向下一条指令。这都是任意的,它就是这样,您的代码或当然机器代码偏移量必须符合架构。
简短的回答看 acorn 文档,三阶段管道,所以想想获取、解码、执行,所以当你执行 pc 时,它会提前获取两条指令。尽管有更深的管道,但非橡子 ARM 继续采用该方案。
指令 a、b、c、d(并非真正的指令,仅用于演示目的)
0x10 a
0x14 b
0x18 c
0x1C d
PC
0x10 fetch a
0x14 fetch b decode a
0x18 fetch c decode b execute a
0x1C fetch d decode c execute b
所以指令 a 位于地址 0x10,但是当它执行时,pc 是 0x18。这是添加到编码中的 8 字节差异。
,在构建第一个 ARM CPU 时,他们做得尽可能简单。
最简单的设计(需要最少数量的晶体管)导致值(当前指令的地址+ 8)几乎(*)所有读取寄存器r15
的指令.
出于这个原因,指令 ADD R15,R15,#100
(在那些旧的 ARM CPU 上)会跳转到当前指令的地址加上 108
。
为了与现有程序兼容,这在较新的 ARM CPU 中没有改变。
(*) 顺便说一句:
对于某些指令,结果是正式的(当前指令的地址 + 12)。在较新的 ARM CPU 上,这些指令(例如 ADD r0,r15,r1,lsl r2
)在读取 r15
时会导致“不可预测的值”。
因此,确实有一些指令在第一批 ARM CPU 上导致了可预测的结果,而在现代 ARM CPU 上不再导致可预测的结果。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。