我正在查看我的代码的汇编输出,并需要以下说明的帮助.
- // -
0x00000fe8: e28fc000 .... ADR r12,{pc}+8 ; 0xff0
0x00000fec: e28cca08 .... ADD r12,r12,#8, 20 ; #0x8000
Run Code Online (Sandbox Code Playgroud)
- // -
根据我的理解,第一条指令导致r12被加载
"{pc value} + 8"即是
"{当前正在执行的指令的地址(0xfe8)加上2个指令(8)} + 8"
第一条指令执行加载0xff8(0xfe8 + 8 + 8)后r12也是如此
关于第2条指令 -
如何计算添加并存储到r12的值?(评论说它的0x8000,虽然我无法理解它是如何得到的)
第一条指令(实际上是伪指令)将PC相关地址加载到R12中.由于指令位于地址0xFE8,因此表达式{pc} +8的计算结果为0xFF0.因此第一条指令的结果是将值0xFF0加载到R12中.评论实际上表明了这一点.
(请注意,ADR是不是一个真正的ARM指令,汇编用指令代替它,如ADD.另外请注意,这个表达式的值在计算装配时间.在程序执行时,PC分领先当前指令的,因处理器的流水线.未来需要多少取决于架构(例如ARM7等)和操作模式(Thumb/ARM).)我冒这里有关于ADR和PC相对表达/寻址的"太多信息"的风险,但如果你不了解幕后发生的事情,很容易被咬伤.)
第二条指令(实际上从右向左读取)有效地表示"取常数0x8,向右旋转20位(与左移12位,32-20 = 12相同),将其加到R12(目前保存0xFF0),并将其存储在R12中." 0x8 << 12 = 0x8000,因此第二条指令导致R12保持0x8000 + 0xFF0 = 0x8FF0.
注意:在您的解释中,当您说"提前2条指令"时,不要陷入这种习惯,将其视为8字节,而不是2条指令.该指令说添加8个字节,它没有说明任何指令.指令不一定是4个字节长(例如,在Thumb中,它们是2个字节;在Thumb2中,它们是2个字节或4个字节,具体取决于指令).