计算机指令和指令跳转

计算机指令

在很早期的时候,没有c语言时,写程序都需要一种很古老的物理设备,叫做“打孔机”,用这种设备写程序要先在脑海里或者在纸上写程序,然后在纸带上或者卡片上打洞,这样要写的程序和要处理的数据就变成一张张卡片,之后交给当时的计算机处理。
在这里插入图片描述
为何早期要用这种方式编写而不用现如今高级语言编写?
因为计算机或者CPU本身没有能力理解这些高级语言,现如今的计算机也是也是仍然只能处理所谓的机器码。
在软硬件接口CPU的作用:
从硬件角度CPU就是一个超大规模集成电路,通过电路实现了加法乘法和各种各样的处理逻辑。
从软件角度讲,CPU是一个执行各种计算机指令的逻辑机器,计算机指令类似CPU能听懂的语言,也可以称作机器语言。
不同的CPU能听懂的语言不太一样,例如Inel的CPU和苹果用的ARM的CPU,两者语言不一样,两种CPU各自支持的语言就是两组不同的计算机指令集。(电脑上编写的程序不能挪到手机上运行,但能挪到另一台电脑上运行,因为这两台电脑CPU有着相同的指令集)
一个计算机程序有着成千上万的指令,但是CPU里面不能放所有的指令,因此计算机程序平时存储在存储器中。
从编译到汇编,代码怎么变成机器码?
把整个程序翻译成一个汇编语言的程序,整个过程是编译成汇编代码,针对汇编代码,再用汇编器把它翻译成机器码,这些机器码由0和1组成,一条条机器码就是一条条计算机指令。
为什么不只能把代码编译成机器码,非得需要汇编代码?
因为机器码根本看不懂,而汇编代码看的时候多少能猜出代码的含义,汇编语言就是给程序员看的机器码,机器码和汇编代码时一样对应的,人类很容易记住add,mov这些英文指令,机器码难以记忆。
解析指令和机器码:
日常用的Intel CPU 有2000条左右的CPU指令,一般来说常见指令可以分为五大类。

  1. 算数类指令:加减乘除,在CPU层面都会变成一条条算数类指令。
  2. 数据传输类指令:给变量赋值,在内存里读写数据,用的都是数据传输类指令。
  3. 逻辑类指令:逻辑上的与或非。
  4. 条件分支指令:日常写的“if/else”。
  5. 无条件跳转指令:调用函数时其实就是发起一个无条件跳转指令。

在这里插入图片描述
例子:一条指令的机器码(MIPS指令)
在这里插入图片描述
打孔代表1,不带孔代表0,这条命令在打孔纸带上的模样是
在这里插入图片描述
0000 0010 0011 0010 0100 0000 0010 0000
该过程打孔过程就类似用人脑“编译”成一张张命令卡片,对应的程序存储在一张张打好孔的卡片上,不存储在设备里。
C语言》汇编语言》机器语言 一般是这样的编译顺序,为何不C语言》机器语言一步到位?
其实是有一步戴维的,gcc如今就可以一个命令直接变成可执行的binary。为了方便debug,可以认为通过机器语言我们也可以反推出汇编语言长什么样子。
汇编语言其实可以理解成机器码的一种别名或者书写方式,不同指令集和体系结构的机器会有不同机器码,高级语言转换成为机器码时,是通过编译器进行的,需要编译器指定编译成哪种汇编/机器码。

指令跳转

CPU在逻辑上可以认为是由一堆寄存器组成,而寄存器就是CPU内部,由多个触发器或者锁存器组成的简单电路,触发器和锁存器就是两种不同原理的数字电路组成的逻辑门。
CPU内部由差不多几百亿个晶体管,一条条计算机指令执行起来很复杂,CPU在软件层面已经做好了封装,对程序员来说,写好的代码变成指令后一条条顺序执行就可以了。
N个触发器或者锁存器就可以组成N位寄存器,能够保存N位数据,比如我们用的64位Intel服务器,寄存器就是64位的。
在这里插入图片描述
PC寄存器(指令地址寄存器),用来存放下一条需要执行的计算机指令的内存地址。
指令寄存器:用来存放当前正在执行的指令。
条件码寄存器:用里面的一个一个标记位,存放CPU进行算术或者逻辑计算的结果。
除以上寄存器外,CPU还有很多用来存储数据和内存地址的寄存器,这样的寄存器通常不止一个,根据存放的数据内容来给它们取名字,例如整数寄存器,浮点数寄存器等等,有些寄存器可以存放数据也可存放地址,一般叫它通用寄存器。

在这里插入图片描述
程序执行时,CPU会根据PC寄存器的地址从内存里把需要执行的指令读取到指令寄存器中执行,然后根据指令长度自增,开始顺序读取下一条指令,可以看到一个程序的一条条指令在内存中是连续保存的,也会一条条顺序加载。一些特殊指令例如跳转指令,会修改PC寄存器里的地址值,这样下一条要执行的指令就不是从内存中顺序加载的了。

在这里插入图片描述
上图,cmp指令比较前后两个操作数的值,这里DWORD PTR代表操作的数据类型是32位整数。[rbp - 0x4]是变量r的内存地址,因此第一个操作数是从内存里拿到的变量r的值,0x0是常量0的16进制表示形式,cmp的比较结果会存入到条件码寄存器中。
如果比较结果是True,就把零标志条件码(ZF)设置为1
cmp指令执行完,pc寄存器会自动自增,开始执行下一条jne指令
跟着jne指令,jump if not equal ,它会查看对应的零标志位,如果是0,会跳转到后面跟着的操作数4a的位置,这个4a对应的是汇编代码的行号,也就是上面设置的else条件里的第一条指令,当跳转发生时,PC寄存器就不再是自增变成下一条指令,而是直接设置为4a这个地址,之后再把4a这个地址加载到指令寄存器。
mov指令第一个操作数eax,代表累加寄存器,第二个操作数0x0则是16进制的0,这条指令无实际用处,作用是一个占位符,和else里的内容结束后的位置一样。
在这里插入图片描述
该图是循环语句的执行过程

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙崎流河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值