计算机组成 -- goto
CPU执行指令
- CPU是由一堆寄存器组成的,而寄存器是由多个触发器(Flip-Flop)或者锁存器(Latches)组成的简单电路
- 触发器和锁存器是两种不同原理的数字电路组成的逻辑门
- N个触发器或者锁存器,就可以组成一个N位的寄存器,能保存N位的数据,64位的Intel服务器,寄存器就是64位的
- 寄存器分类
- PC寄存器(Program Counter Register),也称为指令地址寄存器(Instruction Address Register)
- 用来存放下一条需要执行的计算机指令的内存地址
- 指令寄存器(Instruction Register)
- 用来存放当前正在执行的指令
- 条件码寄存器(Status Register)
- 用里面的一个个标志位(Flag),存放CPU进行算术或者逻辑计算的结果
- 其它
- 整数寄存器、浮点数寄存器、向量寄存器、地址寄存器、通用寄存器
- PC寄存器(Program Counter Register),也称为指令地址寄存器(Instruction Address Register)
- 程序执行
- CPU会根据PC寄存器里面的地址,从内存里把需要执行的指令读取到指令寄存器里面执行
- 然后根据指令长度自增,开始顺序读取下一条指令,一个程序的指令,在内存里面是连续保存的,也会一条条顺序加载
- 特殊指令,如J类指令(跳转指令),会直接修改PC寄存器里面的地址值
- 这样下一条要执行的指令就不是从内存里面顺序加载的了
if-else
1 | // test.c |
1 | $ gcc -g -c test.c |
1 | ...... |
- 对于
r == 0
的条件判断,被编译成了cmp
和jne
这两条指令
cmp
指令比较了前后两个操作数的值DWORD PTR
代表操作的数据类型是32位的整数,[rbp-0x4]
是一个寄存器的地址,从寄存器里拿到的变量r的值- 第2个操作数
0x0
:常量0的16进制表示 cmp
指令的比较结果,会存入到条件码寄存器当中去- 如果比较的结果为True,即
r==0
,就把零标志条件码(对应的条件码是ZF,Zero Flag)设置位1 - Intel CPU的其它标志位
- 进位标志(CF,Carry Flag)、符号标志(SF,Sign Flag)、溢出标志(OF,Overflow Flag)
- 如果比较的结果为True,即
cmp
指令执行完成后,PC寄存器会自动自增,开始执行下一条jne
指令jne = jump if not equal
,jne
指令会查看对应的零标志位,如果为0,会跳转到42的位置- 42对应的是汇编代码的行号,也是else条件里面的第一条指令
- 当发生跳转时
- PC寄存器就不再自增,而是被直接设置成42,CPU再把42地址里的指令加载到指令寄存器来执行
- 跳转到执行地址为42的指令,实际是一条
mov
指令- 该指令将2设置到另一个32位整型的寄存器地址,相当于一个赋值操作
- 然后PC寄存器里的值继续自增,执行
leave
指令
- 如果
r == 0
条件满足,在赋值的mov
指令执行完成后,有一个jmp
的无条件跳转指令,跳转到49(leave
指令)
for
1 | // test.c |
1 | $ gcc -g -c -std=c99 for.c |
1 | ...... |
- 循环是用1e地址上的
cmp
比较指令和jle
条件跳转指令来实现的 jle
跳转的地址,是jle
指令前面的地址14(向前跳转)
参考资料
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.