经过两天的不断查找资料,终于是明白了其中让我搞不懂的地方:一般情况下我们自己编写的汇编代码是比较容易看懂的,就好比我截图中的原汇编代码是:LDR R0 , =0x50000100,使用的是32位立即数寻址方式;但是经过Keil编译之后的汇编代码却是:LDR r0 , [pc , #40],使用的是基于PC寄存器的基址寻址方式,也就是说编译器在编译时会自动去选择合适的方式来实现相同的功能,而且从我了解到的资料中,大部分的立即数寻址方式在最终生成的代码中其实都是基于“文字池”,然后使用PC作为基址的寻址方式。
接下来的关于我询问的“立即数为什么左移2位的”问题,我在查看Thumb指令机器码的时候明白了,这是指令规定好的,而且与ARM的32位的LDR的指令编码方式不一样,我是被我第二个截图中的内容搞晕了,截图中的描述确实是不够详细,我这种新手一下子就遇到死胡同了。
再后来谈到PC值的计算方法,我也从资料中了解到了为什么要加4而不是前两天只知加4而不知道根本原因,加4的原因是Cortex-M0内核使用的是3级流水线结构,而且按16位数据进行取指(即PC每次加2),由于是3级流水线结构,在指令中使用到的PC值的时候实际上PC已经指向第三条指令地址了,所以要加4。后来我提出了在各个内核的处理器中汇编代码不能通用的问题,现在也解决了,原因同上上一条,我们实际在写汇编代码的时候几乎是不会用到PC作为基址的寻址方式(除非是自找难受或者是对所写程序了如指掌的大神),编译器会在编译的时候自动处理,所以不会存在由于流水线级数不同而导致的代码不通用的问题。
最后,感谢你的解答,让我明白不少。 |