计算机组成原理-指令和运算

计算机组成原理-指令和运算

  本文根据徐文浩老师的计算机组成原理记录:计算机组成原理

  CSDN base64 图片显示有问题, 想要个人笔记的可以私我

1 计算机指令

  计算机指令集,英文叫 Instruction Set。这里面的“Set”,其实就是数学上的集合,代表不同的单词、语法。

  要让一段程序在一个 Linux 操作系统上跑起来,我们需要把整个程序翻译成一个汇编语言(ASM,Assembly Language)的程序,这个过程我们一般叫编译(Compile)成汇编代码。

  针对汇编代码,我们可以再用汇编器(Assembler)翻译成机器码(Machine Code)。这些机器码由“0”和“1”组成的机器语言表示。这一条条机器码,就是一条条的计算机指令。这样一串串的 16 进制数字,就是我们 CPU 能够真正认识的计算机指令。

![编译汇编][编译汇编]

  C语言>汇编语言>机器语言 一般是这样的编译顺序,为什么不是 C语言>机器语言 一步到位这样编译呢?

  其实有一步到位的,就是两个步骤都通过一个命令先后执行,顺序完成,gcc现在就可以一个命令直接变成可执行的binary。只是为了方便debug,你可以认为通过机器语言我们也可以反推出汇编语言长什么样子。

  在Linux 操作系统上,可以简单地使用 gcc 和 objdump 这样两条命令,把对应的汇编代码和机器码都打印出来。

$ gcc -g -c test.c
$ objdump -d -M intel -S test.o

1.1 常见 的解析指令和机器码

编号 指令类型 说明 示例命令 示例汇编代码 含义 注释
1 算术类指令 加减乘除,在 CPU 层面,都会变成一条条算术类指令 add add $s1,$s2,$s3 $s1=$s2+$s3 将 s2 和 s3 寄存器中的数相加后的结果放到寄存器 s1 中
2 逻辑类指令 逻辑上的与或非 or or $s1,$s2,$s3 $s1=$s2 | $s3 将 s2 和 s3 寄存器中的数按位取或后的结果放到寄存器 s1 中
3 数据传输指令 给变量赋值、在内存里读写数据,用的都是数据传输类指令 load word load $s1,10($s2) $s1=memory($s2+10) 取 s2 寄存器中的数,加上10偏移量后,找到内存中的字,存入到s1寄存器中
4 条件分支类指令 "if/else"之类的指令 branch on equal beq $s1,$s210 if($s1 == $s2) go to PC+4+10 如果 s1 和 s2 寄存器内的值相等,从程序计数器往后跳10
5 无条件跳转指令 调用函数的时候,就是发起了一个无条件跳转指令 jump j 1000 go to 1000 跳转到 1000 这个目标地址

2 寄存器

  一个 CPU 有多个寄存器, 每个寄存器都有各自的名字; 如 64 位处理器,有 16 个寄存器(RAX、RBX、RCX、RDX、RSI、RDI、RBP、RSP、CS、DS、ES、SS、FS、GS、RIP、RFLAGS)

  三个特殊的寄存器:

![特殊的寄存器][特殊的寄存器]

3 链接

  Linux 和 Windows 中的链接各式不同, linux 下为 ELF 格式, Windows 下为 PE 格式;

  如果我们有一个可以能够解析 PE 格式的装载器,我们就有可能在 Linux 下运行 Windows 程序了。这样的程序真的存在吗?没错,Linux 下著名的开源项目 Wine,就是通过兼容 PE 格式的装载器,使得我们能直接在 Linux 下运行 Windows 程序的。而现在微软的 Windows 里面也提供了 WSL,也就是 Windows Subsystem for Linux,可以解析和加载 ELF 格式的文件

3.1 ELF 链接

   ELF(Execuatable and Linkable File Format) 中文名字叫可执行与可链接文件格式,这里面不仅存放了编译成的汇编指令,还保留了很多别的数据

![ELF文件格式信息][ELF文件格式信息]

3.2 PE 链接

  Windows 的可执行文件格式是一种叫作PE(Portable Executable Format)的文件格式

4 程序装载

  在运行这些可执行文件的时候,其实是通过一个装载器,解析 ELF 或者 PE 格式的可执行文件。装载器会把对应的指令和数据加载到内存里面来,让 CPU 去执行

  实际上装载器需要满足两个要求:

  1. 可执行程序加载后占用的内存空间应该是连续的。执行指令的时候,程序计数器是顺序地一条一条指令执行下去。这也就意味着,这一条条指令需要连续地存储在一起
  2. 正常情况下需要同时加载很多个程序,并且不能让程序自己规定在内存中加载的位置。虽然编译出来的指令里已经有了对应的各种各样的内存地址,但是实际加载的时候,其实没有办法确保,这个程序一定加载在哪一段内存地址上。因为现在的计算机通常会同时运行很多个程序,可能你想要的内存地址已经被其他加载了的程序占用了

4.1 虚拟内存地址

  为了满足这两个基本要求, 可以在内存里面,找到一段连续的内存空间,然后分配给装载的程序,然后把这段连续的内存空间地址,和整个程序指令里指定的内存地址做一个映射

  指令里用到的内存地址叫作虚拟内存地址(Virtual Memory Address),实际在内存硬件里面的空间地址,我们叫物理内存地址(Physical Memory Address)

4.2 内存分段和内存交换

  找出一段连续的物理内存和虚拟内存地址进行映射的方法,我们叫分段(Segmentation)。这里的段,就是指系统分配出来的那个连续的内存空间。

![内存碎片][内存碎片]

  内存碎片的解决方式: 内存交换

4.3 内存分页

  虚拟内存、分段,再加上内存交换,看起来似乎已经解决了计算机同时装载运行很多个程序的问题。不过,这三者的组合仍然会遇到一个性能瓶颈。硬盘的访问速度要比内存慢很多,而每一次内存交换,都需要把一大段连续的内存数据写到硬盘上。所以,如果内存交换的时候,交换的是一个很占内存空间的程序,这样整个机器都会显得卡顿。

  既然问题出在内存碎片和内存交换的空间太大上,那么解决问题的办法就是,少出现一些内存碎片。另外,当需要进行内存交换的时候,让需要交换写入或者从磁盘装载的数据更少一点,这样就可以解决这个问题。这个办法,在现在计算机的内存管理里面,就叫作内存分页(Paging)。

  和分段这样分配一整段连续的空间给到程序相比,分页是把整个物理内存空间切成一段段固定尺寸的大小。而对应的程序所需要占用的虚拟内存空间,也会同样切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间,我们叫页(Page)。从虚拟内存到物理内存的映射,不再是拿整段连续的内存的物理地址,而是按照一个一个页来的。页的尺寸一般远远小于整个程序的大小。

  Linux 下内存页大小的查看方式: getconf PAGE_SIZE

  分页的方式在加载程序的时候,不再需要一次性都把程序加载到物理内存中。当要读取特定的页,却发现数据并没有加载到物理内存里的时候,就会触发一个来自于 CPU 的缺页错误(Page Fault)。操作系统会捕捉到这个错误,然后将对应的页,从存放在硬盘上的虚拟内存里读取出来,加载到物理内存里。

  这种方式,可以运行那些远大于我们实际物理内存的程序。同时,这样一来,任何程序都不需要一次性加载完所有指令和数据,只需要加载当前需要用到就行了。

5 动态链接库

![内存占用的问题][内存占用的问题]

  在 Windows 下,共享库文件就是.dll 文件,也就是 Dynamic-Link Libary(DLL,动态链接库)。在 Linux 下,共享库文件就是.so 文件,也就是 Shared Object(一般也称之为动态链接库)。

![动态链接库][动态链接库]

  对于所有动态链接共享库的程序来讲,虽然共享库用的都是同一段物理内存地址,但是在不同的应用程序里,它所在的虚拟内存地址是不同的。

![共享同一段物理内存][共享同一段物理内存]

5.1 动态链接库寻址

![show_me_poor][show_me_poor]

  在共享库的 data section 里面,保存了一张全局偏移表(GOT,Global Offset Table)。虽然共享库的代码部分的物理内存是共享的,但是数据部分是各个动态链接它的应用程序里面各加载一份的。所有需要引用当前共享库外部的地址的指令,都会查询 GOT,来找到当前运行程序的虚拟内存里的对应位置。而 GOT 表里的数据,则是在加载一个个共享库的时候写进去的。

6 编码与数字

  ASCII 码

ASCII 码

  ASCII 码只表示了 128 个字符,一开始倒也堪用,毕竟计算机是在美国发明的。然而随着越来越多的不同国家的人都用上了计算机,想要表示譬如中文这样的文字,128 个字符显然是不太够用的。于是,计算机工程师们开始各显神通,给自己国家的语言创建了对应的字符集(Charset)和字符编码(Character Encoding)。

  而字符编码则是对应字符集里的这些字符,一一用二进制表示出来。Unicode 就可以用 UTF-8、UTF-16,乃至 UTF-32 来进行编码,存储成二进制。

7 门电路

8 浮点数和定点数

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章