About arm pc value in thumb 16/32bits mixed instructions stream

偶尔善良 提交于 2019-12-08 23:15:30

The PC offset is always 4 bytes in Thumb state. The reason being that it's two instruction fetches ahead, and a Thumb instruction fetch is (conceptually) always a halfword - hence why 32-bit encodings still have the funny byte order of two little-endian halfwords, rather than one little-endian word.

The one "32-bit" encoding in the original Thumb instruction set, bl, had the operation of each halfword defined separately as "prefix" and "suffix" instructions, the neat trick being that whilst executing the first part, the return address is taken directly from the PC, since at that stage it's pointing to the instruction after the second part. By the time Thumb-2 technology came along and made 32-bit encodings a formal thing (including bl retroactively), the PC offset had borne no relation to the actual microarchitecture for several generations*, so changing its defined behaviour to be variable dependent on the instruction stream would have had virtually no benefit and introduced massive compatibility problems.

To further complicate matters, when the PC is used as a base register for addressing operations (i.e. adr/ldr/str/etc.) it is always the word-aligned value that is used, even in Thumb state. So, whilst executing a load instruction at 0x159a, the PC register will read as 0x159e, but the base address of ldr...[pc] is Align(0x159e, 4), i.e. 0x159c. Since PC-relative addressing is normally written by specifying a label rather than calculating offsets manually, this detail can be easy to miss.

* In terms of ARM's own designs, ARM7 was the last microarchitecture based around the original 3-stage pipeline.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!