尝试了解ARM7的流水线
我有这条装配线:
01000AD8: 979FF103 LDRLS PC,[PC,R3,LSL #2]
PC = 0x01000AD8
R3 = 0x00000008
CDPS = 800000D3(所以C=0,Z=0)
当我执行这条线时,PC的新值应该是(如果我正确理解LDRLS*)
PC = 0x01000AD8 + 0x00000008 * 4 = 0x01000AF8
但结果是 0x00000BAC
为什么?
也许我可以补充一点,当执行此行代码时,MMU 被激活。
PS *我在我的研究中没有找到LDRLS中“LS”的含义...
编辑:添加了CPSR值
I have this assembly line :
01000AD8: 979FF103 LDRLS PC,[PC,R3,LSL #2]
With PC = 0x01000AD8
R3 = 0x00000008
CDPS = 800000D3 (so C=0, Z=0)
When I execute this line, the new value for PC should be(if I understand LDRLS correctly*)
PC = 0x01000AD8 + 0x00000008 * 4 = 0x01000AF8
But instead the result is
0x00000BAC
Why?
Maybe I could add that the MMU is activated when this line code is executed.
P.S. * I didn't found the meaning of "LS" in LDRLS in my research...
EDIT : added CPSR value
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个问题:A2-11页:
您忘记将 8 添加到 PC。
第二个问题:A8-124页:
您忘记了“从记忆中加载单词”步骤。
(页码来自 ARMv7-A 的 ARM 架构参考手册。您的页码可能有所不同。)
First problem: Page A2-11:
You forgot to add 8 to PC.
Second problem: Page A8-124:
You forgot the "loads a word from memory" step.
(The page numbers are from the ARM Architecture Reference Manual for ARMv7-A. Your page numbers may differ.)
当用作操作数时,PC 始终位于前面两条指令,因此如果是手臂模式,则添加 8,如果是拇指模式,则添加 4。
LDR是指令:加载寄存器。 LS 表示如果 LDREQ 相等,则负载较低或相同。在手臂中搜索“条件代码”。本例中指令 0x9 的前四位是 LS,如果较低或相同则执行。大多数指令的这些位为 0xE,表示始终执行。
所有 ARM 指令都使用高四位作为条件代码,基本上可以在逐条指令的基础上有条件地执行,在这种情况下,只有在 C 标志被清除或 Z 标志被设置时,它才会执行 LDR。如果它执行加载,那么它就是您计算时的地址,加上 8,因为地址计算的 PC 输入是起始地址之前的两个指令,那么结果是从该地址加载到 PC 中,所以基本上是这样是到计算地址的条件分支。一个分支表。通常你会有一个带有 [ra,rb,lsl #2] 的分支表,其中 ra 是分支表的基地址,rb 是该表的基于个数的索引(元素号 0 或 1 或 2),lsl 2 轮次字地址的索引,因为这些是 32 位指令。该表包含分支目的地的地址。用作基础的 PC 意味着该指令之后的下一条指令可能是无条件分支到非条件情况,如果不是 LS,则在表上进行分支,之后的指令是 R3 = 0 情况,R3 = 1 之后的指令案等。如果编译器知道 R3 永远不会小于某个数字,那么它可能会在该指令之后使用更多指令,然后再在表格上移动/移动。
无论如何,看看 ARM ARM(现在称为 ARMv5 ARM ARM 或传统 ARM ARM 或类似的东西)。搜索“条件字段”或“条件代码”以查找该表。如果 z 标志设置为 ADDEQ,则助记符扩展将附加到指令 ADD 上。如果 N 标志设置为 SUBMI,则减去,等等。
The PC is always two instructions ahead when used as an operand so add 8 if arm mode and 4 if thumb mode.
LDR is the instruction: load register. The LS means if lower or same LDREQ would be load if equal. Search for "condition codes" in the arm arm. The top four bits in the instruction 0x9 in this case is the LS, execute if lower or same. Most instructions have those bits as 0xE meaning always execute.
All of the ARM instructions use the upper four bits as a condition code, basically on an instruction by instruction basis you can conditionally execute, in this case it will only perform the LDR if the C flag is clear or the Z flag is set. IF it performs the load then it is the address as you were calculating it, plus 8 because the PC input to the address calculation is two instructions ahead of the starting address, then the result is a load from that address into the PC so basically this is a conditional branch to a computed address. A branch table. Normally you would have a branch table with [ra,rb,lsl #2] where ra is the base address of the branch table, rb is the ones based index into that table (element number 0 or 1 or 2) and lsl 2 turns the index into a word address since these are 32 bit instructions. the table contains addresses to branch destinations. The PC being used as the base means the next instruction after this instruction is probably an unconditional branch to non-conditional case if not LS then branch over the table, the instruction after that is the R3 = 0 case the one after that R3 = 1 case and so on. if the compiler knew that R3 could never be smaller than some number then it may have used more instructions after this one before moving over/around the table.
Anyway look at an ARM ARM (now called something like the ARMv5 ARM ARM or legacy ARM ARM or something like that). search for "the condition field" or "condition codes" to find the table. The mnemonic extension is tacked onto the instruction ADD if z flag is set is an ADDEQ. Subtract if the N flag is set is SUBMI, etc.