确实如此...
下面是一个示例: C 程序:
int f,g,y;//global variables
int sum(int a, int b){
return (a+b);
}
int main(void){
f = 2;
g = 3;
y = sum(f, g);
return y;
}
编译成汇编:
00008390 <sum>:
int sum(int a, int b) {
return (a + b);
}
8390: e0800001 add r0, r0, r1
8394: e12fff1e bx lr
00008398 <main>:
int f, g, y; // global variables
int sum(int a, int b);
int main(void) {
8398: e92d4008 push {r3, lr}
f = 2;
839c: e3a00002 mov r0, #2
83a0: e59f301c ldr r3, [pc, #28] ; 83c4 <main+0x2c>
83a4: e5830000 str r0, [r3]
g = 3;
83a8: e3a01003 mov r1, #3
83ac: e59f3014 ldr r3, [pc, #20] ; 83c8 <main+0x30>
83b0: e5831000 str r1, [r3]
y = sum(f,g);
83b4: ebfffff5 bl 8390 <sum>
83b8: e59f300c ldr r3, [pc, #12] ; 83cc <main+0x34>
83bc: e5830000 str r0, [r3]
return y;
}
83c0: e8bd8008 pop {r3, pc}
83c4: 00010570 .word 0x00010570
83c8: 00010574 .word 0x00010574
83cc: 00010578 .word 0x00010578
见上面 LDR 的 PC 值——这里用于将变量 f,g,y 的地址加载到 r3。
83a0: e59f301c ldr r3, [pc, #28];83c4 main+0x2c
PC=0x83c4-28=0x83a8-0x1C = 0x83a8
PC 的值就是当前执行指令的下一条指令。由于ARM使用32位指令,但它使用字节地址,所以+ 8表示8字节,两条指令的长度。
所以附上了 ARM archi 的 5 阶段管道 linefetch、decode、execute、memory、writeback
ARM 的 5 级流水线
PC寄存器每个时钟加4,所以当指令冒泡执行时——当前指令,PC寄存器已经过去了2个时钟!现在是+ 8。这实际上意味着:PC指向“获取”指令,当前指令意味着“执行”指令,所以PC意味着下一个要执行的指令。
顺便说一句:图片来自哈里斯的数字设计和计算机体系结构 ARM 版的书