理解计算机系统_程序计数器PC的实现
前言
以<深入理解计算机系统>(以下称“本书”)内容为基础,对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定
引入
试分析程序计数器PC的工作.此内容与本书第三章内容相关,尝试理解底层的一些运行机制.
回顾底层数据表示
基本表达
数据由地址和值两部分组成.地址用于数据的传递,值表示数据的用途.如下表
| 数据 | 地址 | 值 |
| 示例1 | 0x12345678 | 1234 |
| 示例2 | 0x12345680 | 1235 |
假设有指令
movq 0x12345678,%rax
表示把值1234放入寄存器%rax中.如果再执行以下指令
movq %rax,0x12345680
表示把1234放入地址0x1234567c中,此时原来的值1235变成1234.
每条指令操作的数据不能超过字长单元,超过字长单元的数据用"指针+偏移"来访问.
指针
当某个数据(假设为数据A)的值是另一个数据(假设为数据B)的地址时,表达为数据A指向数据B.此时可以操作A访问数据B地址开头的一连串数据.指针是用间接运算符"()"---一对小括号来实现的.
movq $0x12345678,%rax
addq $4,(%rax)
把地址0x12345678作为立即数传给寄存器%rax,此时寄存器%rax在指令中表示值0x12345678,当加上"()"后表示以其值为地址的数据的值,即(%rax)表示1234,当指令addq执行以后,数据--地址为0x12345678的数据,其值变为1238.
指针可以偏移,用%rax访问0x12345678以后的连续数据.因为是8字节,所以还可以这样
addq $8,%rax //指针指向下一个数据,偏移8字节,实际到了0x12345680
movq (%rax),0x12345678 //此时(%rax)表示0x12345680中的值1235,传给地址0x12345678
数据--地址为0x12345678的数据,其值变为1235.这是指针在底层的实现过程.
指针很强大,此外还有一点:底层都是些二进制数,是"地址"或"值"由程序员自己控制.
=============================内容分割线↓===================================
!笔者前面关于leaq的用法有误,把leaq当成指针来用是不对的.应该用move指令把地址当立即数传给寄存器.之前的就不修改了,如果有朋友看到以当前写法为准.
因为在写汇编语言的时候并没有测试所以没有发现,但汇编只是为了理解计算机底层运作,实际工作中基本不会用,所以问题也不大不用纠结:)
=============================内容分割线↑===================================
程序计数器PC
如图所示:

由于指令有一元操作,leaq,二元操作,移位等操作,指令间长短不一,所以与之配套的应有一张表

当PC指向指令码1的初始地址addr后,查询配套表,找到偏移的字节数,当PC指向指令码2时,PC加上相应的数字.以此类推.指令码和操作码都是二进制数(指令码具体操作不用关心,由底层电路实现)
指令=指令码+若干操作码.PC指向第一个指令码的初始地址,并根据字节偏移指向下一个指令码的地址.假设指令码固定占用8个字节,那么PC取到每条指令前8个字节,执行对应的逻辑.
小结
简单分析程序计数器PC的实现
