在拇指关于ARM的PC值16/32位混合指令流 [英] About arm pc value in thumb 16/32bits mixed instructions stream

查看:393
本文介绍了在拇指关于ARM的PC值16/32位混合指令流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读了几篇文章,包括问题在这里SO <一个href=\"http://stackoverflow.com/questions/24091566/understanding-the-nature-of-arm-pc-register\">Understanding ARM PC寄存器的性质,PC寄存器的值实际上是当前执行指令的地址加提前2条指令,因此在ARM状态下它是+8字节(2 * 32位)。

I read a couple of articles including question here in SO Understanding the nature of ARM PC register, that pc register value is actually current executing instruction address plus 2 instructions ahead, so in ARM state it's +8 byte (2*32bits).

我的问题是,对于拇指的状态,有可能是16位或32位的指令,它意味着PC取地址可能是+4字节或分别为16/32位指令+8字节偏移?

My question is that, for thumb state, there could be 16bits or 32bits instructions, does it mean that the fetching pc address could be an offset of +4 bytes OR +8 bytes for 16/32bits instructions respectively?

例如:

279ae6: f8df 9338   ldr.w   r9, [pc, #824] --> pc value= 279aea or 279aee
279aea: f44f 7380   mov.w   r3, #256
279aee: 48cd        ldr r0, [pc, #820]

我做更多的测试与以下code:

I did more test with following code:

1598:   467b        mov r3, pc
159a:   f8bf 4000   ldrh.w  r4, [pc]    ; 159c
159e:   46f9        mov r9, pc
15a0:   f83f 5001   ldrh.w  r5, [pc, #-1]   ; 15a3
15a4:   f83f 6002   ldrh.w  r6, [pc, #-2]   ; 15a6
15a8:   f83f 7003   ldrh.w  r7, [pc, #-3]   ; 15a9
15ac:   f83f 8004   ldrh.w  r8, [pc, #-4]   ; 15ac
15b0:   f04f 0908   mov.w   r9, #8
15b4:   f8d9 0008   ldr.w   r0, [r9, #8]    ; Trigger crash to check registers

大跌后,寄存器是:

Upon crash, registers are:

I/DEBUG   ( 2632): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10
I/DEBUG   ( 2632):     r0 b8ef4fc0  r1 aca6bb6c  r2 00000000  r3 aca7c59c
I/DEBUG   ( 2632):     r4 00004000  r5 00003f50  r6 00006002  r7 000003f8
I/DEBUG   ( 2632):     r8 0000f83f  r9 00000008  sl 00000000  fp aca6bbc0
I/DEBUG   ( 2632):     ip aca7c591  sp aca6bb40  lr acab722d  pc aca7c5b4  cpsr 60070030

在上面code注释显示的地址(159℃/ 15A3 / 15a6 / 15a9 / 15AC)由objdump的产生,我检查这些位置'与寄存器的内容,似乎所有的权利。

The addresses shown in above code comments(159c/15a3/15a6/15a9/15ac) are generated by objdump, I checked these positions' contents with registers', seem all right.

16位instrucion:

for 16 bit instrucion:

1598:   467b        mov r3, pc  ;    // r3 = 1598 + 4 = 159c, correct for +4 theory

虽然32位Thumb指令:

While for 32bit thumb instruction:

159a:   f8bf 4000   ldrh.w  r4, [pc]    ; // ld addr = 159a + 2 = 159c, where the content is 4000(hw), exactly r4 shows
                                        ; // Inconsistent with +4 theory

这样,对于32位指令,PC阅读= PC执行+2。我缺少什么?现在我真搞不清楚PC抵消。

By this, for 32 bit instruction, pc read = pc executing +2. Am I missing anything?? Now I'm really confused about pc offset.

顺便说一句,这是一个使用thumb2 armv7a平台。

BTW, this is armv7a platform using thumb2.

感谢你们。

推荐答案

在PC偏移始终在Thumb状态下4个字节。原因是,这两个指令的的进取,Thumb指令取(概念)总是一个半字 - 因此为什么32位编码还有两个小尾数半字的搞笑字节顺序,而不止一个小端字。

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.

扰32位编码原始Thumb指令集, BL ,不得不为preFIX,并分别定义的每个半字的操作后缀指令,所述整齐特技在于同时执行的第一部分,返回地址被直接取自个人计算机中,由于在该阶段它的第二部分之后指向该指令。到时候Thumb-2技术来了,并提出32位编码的正式的东西(的包括 BL 追溯),在PC偏移过得紧< A HREF =htt​​p://infocenter.arm.com/help/topic/com.arm.doc.ddi0338g/I1002919.html相对=nofollow>没有关系,几代实际的微架构 < SUP> * ,所以改变其定义的行为是可变取决于指令流将不得不几乎没有任何的好处,并推出大规模的兼容性问题。

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.

当PC作为基址寄存器寻址操作(即 ADR / LDR / STR /等)。它始终是字对齐的即用,即使在Thumb状态值。因此,虽然在执行一个0x159a加载指令时,PC寄存器的阅读的为0x159e,但 LDR ...的基地址[PC] 对齐(0x159e,4),即0x159c。由于PC相对寻址通常由指定的标签,而不是手工计算抵消写的,这个细节可以很容易错过。

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.

<子> *在ARM自己的设计方面,ARM7是根据各地原有的3级流水线最后的微架构。

这篇关于在拇指关于ARM的PC值16/32位混合指令流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆