计算机组成原理学习笔记(1)

冯.诺依曼结构

冯.诺依曼体系结构示意图

1.中央处理器(Central Processing Unit,CPU):算术逻辑单元(Arithmetic Logic Unit,ALU),包含指令寄存器(Instruction Reigster)和程序计数器(Program Counter)的控制器单元(Control Unit/CU)
2.内存(Memory):存储数据(Data)和指令(Instruction)
3.主板(Motherboard)
4.输入(Input)/ 输出(Output)设备:通过主板上的南桥(SouthBridge)芯片组,来控制和 CPU 之间的通信的
5.GPU(Graphics Processing Unit,图形处理器)
运算器、控制器、存储器、输入设备和输出设备

计算机性能和功耗

性能:响应时间、吞吐率或带宽(Throughput)

时钟周期时间,CPU主频,取决于计算机硬件
每条指令的平均时钟周期数(CPI)
程序的 CPU 执行时间 = 指令数×CPI×Clock Cycle Time

功耗:超大规模集成电路(VLSI)增加密度、提升主频都会带来耗电和散热问题
功耗~=1/2负载电容电压的平方开关频率晶体管数量
提升制程:同样面积下,晶体管造的小一点
8086 5MHz 5V i9 5GHz 1V
降低电压主频提升了 1000 倍,但是功耗只增长了 40 倍

多核CPU,提升吞吐率

阿姆达尔定律(Amdahl’s Law):优化后的执行时间=受优化影响的执行时间/加速倍数+不受影响的执行时间
加速大概率事件:GPU、TPU
流水线提高性能:将CPU指令执行过程拆分,细化运行
预测:分支和冒险、局部性原理

计算机指令和运算

高级语言 编译(Compile) 汇编语言(ASM,Assembly Language) 汇编器(Assembler)机器码(Machine Code)
计算机高级语言至机器码翻译
CPU常见指令
CPU常见指令

MIPS指令集
MIPS指令集
32 位的整数,高 6 位叫操作码(Opcode)

R 指令:算术和逻辑操作

  • rs(Source Register) 通常用于指定第一个源操作数所在的寄存器编号
  • rt(Target Register) 通常用于指定第二个源操作数所在的寄存器编号
  • rd(Destination Register) 通常用于指定目的操作数(保存运算结果)的寄存器编号
  • shamt(shift amount) 用于指定移位指令进行移位操作的位数,对于非移位指令,该域设为0

例:rs 代表第一个寄存器 s1 的地址是 17,rt 代表第二个寄存器 s2 的地址是 18,rd 代表目标的临时寄存器 t0 的地址,是 8,位移量是 0。
在这里插入图片描述

I 指令:数据传输、条件分支,以及运算时使用的并非变量而是常数时
J 指令:跳转指令,高 6 位之外的 26 位都是一个跳转后的地址

在这里插入图片描述
1.PC 寄存器(Program Counter Register):指令地址寄存器(Instruction Address Register),用来存放下一条需要执行的计算机指令的内存地址。
2.指令寄存器(Instruction Register):存放当前正在执行的指令
3.条件码寄存器(Status Register):标记位(Flag)存放 CPU 进行算术或者逻辑计算的结果,如零标志条件码(ZF,Zero Flag)、进位标志(CF,Carry Flag)、符号标志(SF,Sign Flag)以及溢出标志(OF,Overflow Flag)

程序的执行和跳转

在这里插入图片描述

对于 r == 0 的条件判断,被编译成了 cmp 和 jne 这两条指令
1.cmp 比较前后两个操作数的值,DWORD PTR 代表操作的数据类型是 32 位的整数,[rbp-0x4] 是一个寄存器的地址。第一个操作数就是从寄存器里拿到的变量 r 的值。第二个操作数 0x0就是设定的常量0的16进制表示。cmp 指令的比较结果,会存入到条件码寄存器当中去

2.r == 0就把零标志条件码(对应的条件码是 ZF,ZeroFlag)设置为 1,cmp 指令执行完成之后,PC 寄存器会自动自增,开始执行下一条 jne 的指令

3.jne 指令(jump if not equal) 会查看对应的零标志位。如果为 0,会跳转到汇编代码行号为4a的位置当跳转发生的时候,PC 寄存器就不再是自增变成下一条指令的地址,而是被直接设置成4a这个地址,CPU 再把 4a 地址里的指令加载到指令寄存器中来执行。

4.mov 指令赋值2到对应的寄存器里去, 0x0 没有实际的作用,是一个占位符。jmp 无条件跳转指令,跳转的地址就是51。main 函数没有设定返回值,而 mov eax, 0x0 其实就是给 main 函数生成了一个默认的为0的返回值到累加器里面。

在这里插入图片描述

函数调用

int static add(int a, int b)
{
	0: 55 push rbp
	1: 48 89 e5 mov rbp,rsp
	4: 89 7d fc mov DWORD PTR [rbp-0x4],edi
	7: 89 75 f8 mov DWORD PTR [rbp-0x8],esi

	return a+b;

	a: 8b 55 fc mov edx,DWORD PTR [rbp-0x4]
	d: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
	10: 01 d0 add eax,edx
}
	12: 5d pop rbp
	13: c3 ret
	0000000000000014 <main>:

int main()
{
	14: 55 push rbp
	15: 48 89 e5 mov rbp,rsp
	18: 48 83 ec 10 sub rsp,0x10

	int x = 5;

	1c: c7 45 fc 05 00 00 00 mov DWORD PTR [rbp-0x4],0x5

	int y = 10;

	23: c7 45 f8 0a 00 00 00 mov DWORD PTR [rbp-0x8],0xa

	int u = add(x, y);

	2a: 8b 55 f8 mov edx,DWORD PTR [rbp-0x8]
	2d: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
	30: 89 d6 mov esi,edx
	32: 89 c7 mov edi,eax
	34: e8 c7 ff ff ff call 0 <add>
	39: 89 45 f4 mov DWORD PTR [rbp-0xc],eax
	3c: b8 00 00 00 00 mov eax,0x0

}
	41: c9 leave
	42: c3 ret

add 函数编译之后,代码先执行一条 push 指令和 mov 指令;函数执行结束时,又执行一条 pop 和 ret 指令-压栈(Push)和出栈(Pop)操作

后进先出(LIFO,Last In First Out)

整个函数 A 所占用的所有内存空间,就是函数 A 的栈帧(Stack Frame)
在这里插入图片描述

push rbp进行压栈, rbp叫栈帧指针(Frame Pointer),存放了当前栈帧位置的寄存器。push rbp把main 函数的栈帧的栈底地址,压到栈顶

函数 add 执行完成之后,又会分别调用第 12 行的pop rbp将当前的栈顶出栈

栈溢出(stack overflow):函数调用层数太多,在不断地压栈过程中,将整个栈空间填满

函数内联(Inline):在定义函数的地方,加上 inline 的关键字,CPU需要执行的指令数变少,根据地址跳转的过程不需要,压栈和出栈的过程也不用了
在这里插入图片描述

静态链接与ETF格式
可执行文件(Executable Program) 目标文件(Object File)链接器(Linker)通过链接器(Linker)把多个目标文件以及调用的各种函数库链接起来,才能得到一个可执行文件

C 语言代码 - 汇编代码 - 机器码
1.编译(Compile)、汇编(Assemble)以及链接(Link),生成一个可执行文件
2.通过装载器(Loader)把可执行文件装载(Load)到内存中,CPU 从内存中读取指令和数据,来开始真正执行程序
在这里插入图片描述

Linux 可执行文件和目标文件所使用的都是可执行与可链接文件格式(Execuatable and Linkable File Format,ELF),ELF 文件格式把各种信息,分成一个一个的 Section 保存起来
在这里插入图片描述
程序装载与执行

装载器,解析ELF 或PE格式可执行文件,把对应的指和数据加载到内存里面来,让 CPU 去执行
1.可执行程序加载后占用的内存空间应该是连续的
2.需要同时加载很多个程序,并且不能让程序自己规定在内存中加载的位置

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

找出一段连续的物理内存和虚拟内存地址进行映射的方法,分段
在这里插入图片描述

内存碎片(Memory Fragmentation)
在这里插入图片描述

内存交换(Memory Swapping)

内存分页(Paging):把整个物理内存空间切成一段段固定尺寸的大小,让需要交换写入或者从磁盘装载的数据更少一点,从虚拟内存到物理内存的映射,按照一个一个页来的
在这里插入图片描述
动态链接:同样功能的代码,在不同的程序里面,不需要各占一份内存空间

共享库(Shared Libraries):编译出来的共享库文件的指令代码,是地址无关码(Position-Independent Code)
Windows .dll文件 Linux .so文件
在这里插入图片描述
相对地址(Relative Address)
全局偏移表(Global Offset Table,GOT)
程序链接表(Procedure Link Table,PLT)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值