我有这条流水线:
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。
P.S。 *在我的研究中,我没有在LDRLS中找到“LS”的含义......
编辑:添加了CPSR值
答案 0 :(得分:3)
第一个问题:第A2-11页:
执行ARM指令时,PC读取的地址为 当前指令加上8。
您忘记将8添加到PC。
第二个问题:第A8-124页:
加载寄存器根据基址寄存器值和偏移寄存器值计算地址,从存储器加载字,并将其写入寄存器。
您忘记了“从记忆中加载一个单词”步骤。
(页码来自ARMv7-A的ARM体系结构参考手册。您的页码可能有所不同。)
答案 1 :(得分:2)
当用作操作数时,PC总是提前两条指令,因此如果是手臂模式则添加8,如果是拇指模式则增加4。
LDR是指令:加载寄存器。 LS表示如果相等则加载较低或相同的LDREQ。在臂臂中搜索“条件代码”。在这种情况下,指令0x9中的前四位是LS,如果更低或相同则执行。大多数指令都将这些位作为0xE意味着始终执行。
所有ARM指令都使用高4位作为条件代码,基本上在逐条指令的基础上可以有条件地执行,在这种情况下,只有在C标志清零或Z标志为0时才执行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等。