计算机中的指令跳转
Posted ᝰFour Years
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机中的指令跳转相关的知识,希望对你有一定的参考价值。
前言
在上一章中说了,高级语言为什么怎么样成为计算机能够读懂的语言,下面就来说说这些计算机能够读懂的语言中,他们究竟是如何设计的
CPU是如何执行指令的?
在我们现实常用的CPU中,有几百亿的晶体管通过电路起来,在逻辑上我们可以认为CPU就是由一个个寄存器所组成,而CPU的内部,是由多个触发器或者锁存器组成的简单电路。N个触发器或者锁存器就能组成一个N位寄存器
在CPU中有很多功能不同的寄存器
- PC寄存器,他是指令地址寄存器,是用来存放下一条需要执行的计算机指令的内存地址
- 指令寄存器,是用来存放当前正在执行的指令
- 条件码寄存器,是用来存放正在执行的指令
在其他的还有一些通用的寄存器,既可以存放数据,又可以存放地址
阿萨
实际上,在一个程序运行的时候,CPU会根据PC寄存器中的地址,从内存把需要执行的指令读取到指令寄存器中执行,然后另指令长度自增,开始顺序读取下一条指令,里面指令在内存中是连续保存的,也会一条条顺序加载。
if else 就是程序的跳转
下面我们看一个简单的程序
#include <time.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int r = rand() % 2;
int a = 10;
if (r == 0)
{
a = 1;
} else {
a = 2;
}
我们将他编译为汇编代码
if (r == 0)
3b: 83 7d fc 00 cmp DWORD PTR [rbp-0x4],0x0
3f: 75 09 jne 4a <main+0x4a>
{
a = 1;
41: c7 45 f8 01 00 00 00 mov DWORD PTR [rbp-0x8],0x1
48: eb 07 jmp 51 <main+0x51>
}
else
{
a = 2;
4a: c7 45 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2
51: b8 00 00 00 00 mov eax,0x0
}
我们可以看到在上面,if判断语句被编写为cmp和jne命令
cmp命令会去比较上面两个值的,同时它会将比较结果存在条件码寄存器中,如果比较的结果为True,就会把零标识码设置为1,cmp命令执行完之后,pc寄存器就会开始自增。
jne指令的意思就是jump if not equal的意思,他会去查看零标识码,如果为0的话,就会跳转到后面4a的位置,pc寄存器中存的就会变成4a,之后CPU就会将CPU的指令加载到指令寄存器中执行
这条 mov 指令的第一个操作数 eax,代表累加寄存器,第二个操作数 0x0 则是 16 进制的 0 的表示。这条指令其实没有实际的作用,它的作用是一个占位符。我们回过头去看前面的 if 条件,如果满足的话,在赋值的 mov 指令执行完成之后,有一个 jmp 的无条件跳转指令。跳转的地址就是这一行的地址 51。我们的 main 函数没有设定返回值,而 mov eax, 0x0 其实就是给 main 函数生成了一个默认的为 0 的返回值到累加器里面。if 条件里面的内容执行完成之后也会跳转到这里,和 else 里的内容结束之后的位置是一样的。
在上面我们说过打孔卡的原理,打孔卡会一条一条的读取指令,然后执行,如果检测到跳转的指令,机器将带动纸片移动到跳转的位置
循环
int main()
{
int a = 0;
for (int i = 0; i < 3; i++)
{
a += i;
}
}
他的汇编代码如下
for (int i = 0; i <= 2; i++)
b: c7 45 f8 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0
12: eb 0a jmp 1e
{
a += i;
14: 8b 45 f8 mov eax,DWORD PTR [rbp-0x4]
17: 01 45 fc add DWORD PTR [rbp-0x8],eax
1a: 83 45 f8 01 add DWORD PTR [rbp-0x4],0x1
1e: 83 7d f8 02 cmp DWORD PTR [rbp-0x4],0x2
22: 7e f0 jle 14
24: b8 00 00 00 00 mov eax,0x0
}
可以看见循环和上面if else的不同,他的跳转指令在jle之前,通过不断地判断,在判断不正确之前,不断重复前面的操作,直到jle满足,才执行后面的操作
实际上在汇编层面上的语言类似于我们C语言中的goto,直接指定地址去跳转,但是goto是无条件的跳转,而在这里是需要经过判断的
总结
我们发现我们使用三个简单的寄存器就可以完成程序的if else等操作,就是pc寄存器保存下一次的指令,指令寄存器记录当前正在执行的指令,并通过自增操作走向下一个指令,同时使用条件码寄存器进行判断,我们就能进行判断,从而实现循环和判断
以上是关于计算机中的指令跳转的主要内容,如果未能解决你的问题,请参考以下文章