计算机组成原理指令格式例题,计算机组成原理指令系统例题

  计算机组成原理指令格式例题,计算机组成原理指令系统例题

  当你学习编写程序时,你有没有想过在过去计算机程序是如何编写的?

  其实我当时并不想这样,而是用了一种叫“穿孔卡”的老式物理设备。如果用这种设备写程序,就不能像现在这样拿出键盘打字了。你必须把程序记在脑子里或纸上,然后在纸带或卡片上打孔。这样写出来的程序和处理过的数据就变成了纸带或卡片,然后交给当时的计算机进行处理。

  这种打孔胶带是不是和我们现在考试用的答题卡差不多?当时人们在特定位置打孔或不打孔,用“0”和“1”来表示。

  为什么早期的计算机程序不能像我们一样使用打孔卡,用C、Python这样的高级语言编写?原因很简单。可以说,计算机或CPU本身并不具备理解这些高级语言的能力。即使在2019年的今天,我们使用的现代个人电脑也只能处理所谓的“机器代码”,即类似“0”和“1”的一系列数字/

  那么,我们每天用高级语言编写的程序,最后是如何变成“0”和“1”的链条的呢?CPU是如何处理这一系列“0”和“1”的?今天我们就好好介绍一下“机械代码”和“计算机指令”到底是怎么回事。

  CPU在软硬件接口上对我做了什么?人们常说CPU是电脑的大脑。整个CPU就是中央处理器,中文就是中央处理器。

  前面说过,从硬件的角度来看,CPU是超大规模集成电路,通过电路实现加法、乘法甚至各种处理逻辑。

  软件在工程师看来,CPU就是运行http://www.sina.com/(指令代码)的各种逻辑机。这里的计算机指令就像是一种CPU可以理解的语言,也叫http://www.sina.com/(机器语言)。

  根据CPU的不同,你能听懂的语言也不同。比如我们的电脑用的是英特尔CPU。苹果手机用的是ARM的CPU。他们能听懂的语言不太一样。两个CPU支持的语言是两套不同的http://www.sina.com/(指令集)。其中“集合”实际上是一个数学集合,代表不同的单词和语法。

  所以,如果我们在自己的电脑上写一个程序,复制安装到自己的手机上,效果并不好。为什么这么说?是因为两种语言不通。另一方面,一台计算机上的程序只要简单地复制到另一台计算机上,就可以正常运行。因为这两个CPU有相同的指令集。也就是说,这些语言是通用的。

  一个计算机程序不仅由一条指令组成,而且由成千上万条指令组成。然而,CPU中并不总是有所有的指令,所以计算机程序通常存储在内存中。内存中存储这些程序指令的计算机称为http://www.sina.com/(存储程序计算机)。

  在这里,你可能会问,有些计算机不就是存储程序的类型吗?实际上,在现代计算机出现之前,聪明的工程师发明了一种叫做插板计算机的计算器。直译为“插线板电脑”。在各种插座和插口覆盖的板上,工程师用不同的代码链接不同的插座和插口,执行各种计算任务。下面这张照片是IBM的插件板。有蒸汽穿刺的感觉吗?

  从编译到汇编,代码如何变成机器码?了解了计算机指令和计算机指令集之后,接下来,我们来看看平时写的代码是如何变成计算机指令,最后由CPU执行的。让我们来看一个有点现实的C语言程序。

  //test . cint main(){ int a=1;int b=2;a=a b;}这是一个比较简单的C语言程序,即使不懂C语言也应该懂。我们把1和2分别代入两个变量A和B,然后把两个变量A和B的值相加,再代入整个变量A。

  要使这个程序在Linux系统上运行,必须将整个程序翻译成ASM(汇编语言)程序。这个过程通常称为编译)并成为汇编代码。

  汇编代码可以用汇编程序翻译成机器码。这些机器代码由“0”和“1”组成的机器语言来表示。机器代码,计算机指令,一系列十六进制数字,是我们CPU真正能识别的计算机指令。

  在Linux系统上,可以简单地使用gcc和objdump来打印相应的汇编代码和机器码。

  在gcc-g-CT est . c $ objdump-d-Mintel-stest . o中可以看到,左边有很多数字。这些是机器代码。右边是一系列的push、mov、add和pop。

  等等,这些是对应的汇编代码。一行C语言代码可以只对应一个机器码和汇编代码,也可以对应两个机器码和汇编代码。汇编代码和机器码是一一对应的。

  测试o:

  文件格式elf 64-x86-64部分的反汇编。text:0000000000000000 main:int main(){ 0:55 push RBP 1:48 89 E5 mov RBP,RSP int a=1;4:C7 45 fc 01 00 00 00 mov DWORD PTR[RBP-0x 4],0x 1 int b=2;b:C7 45 F8 02 00 00 00 mov DWORD PTR[RBP-0x 8],0x2a=a b;12: 8B45F8 MOV EAX,DWORD PTR [RBP-0x8] 15: 01 45FC加DWORD PTR [RBP-0x4],EAX} 18: 5D POP RBP19: C3RET这个时候你可能又要问了。当我们实际使用GCC(GUC编译器套件,GUI编译器集合)编译器时,我们可以直接使用,原因很简单。当你看着一串数字代表的机器码,你是不是很迷茫?但是即使你没有学过汇编代码,在阅读的时候也可以“猜”出这些代码的一些含义。

  因为汇编代码其实就是“程序员的机器码”,也正因为如此,机器码和汇编代码是一一对应的。我们很容易记住add、moc等英文的指令,而8b 45 f8等指令却非常难记住,因为很难一下子就理解它们在做什么。虽然早些年在网上广为流传,但这位大神程序员是用刀把操作系统的梗刻在光盘上的。不过估计浪费的卡比打卡写哥哥程序用的卡多得多。

  从高级语言到汇编代码,再到机器码,都是常规的开发程序,最后变成CPU可以执行的计算机指令的过程。

  分析指令和机器码来理解这个过程。让我们放大下面的部分,看看这一行授权汇编代码和机器指令到底是什么意思。

  先从平时的电脑和手机说起。这些设备的CPU有什么指令?有不少。我们日常的Intel CPU大概有2000条CPU指令,太多了,没法全部解释。然而,一般来说,常见的指令可以分为五类:

  第一类是算术类指令。我们的加减乘除,在CPU层面,会变成算术指令。

  第二类是数据传输类指令。给变量赋值和在内存中读写数据都使用数据传输指令。

  第三类是逻辑类指令。逻辑AND or NOT就是这种指令。

  第四类是条件分支类指令。我们每天写的if/else,其实就是条件分支指令。

  最后一类是无条件跳转指令。要写一些更大的程序,我们经常需要写一些函数或者方法。调用一个函数的时候,其实是一个无条件跳转指令。

  可能一下子记不住,或者一下子领会不了这些说明的意思。这里有一张桌子。

  我们来看看汇编程序是如何把相应的汇编代码翻译成机器码的。

  我们说过,不同的CPU有不同的指令集,对应不同的汇编语言和不同的机器码。为了方便大家快速理解这个机器码的计算方法,我们选择最简单的MIPS指令集来看看机器码是如何生成的。

  MIPS是MIPS技术公司在80年代中期设计的一套CPU指令集。最近,MIPS公司已经完全开放了它的整个指令集和芯片架构。想深入学习CPU和指令集的同学可以看看。

  MIPS的指令是一个32位整数。高6位称为操作码(操作码),表示这条指令是什么类型的指令。剩下的26位有三种格式,分别是R,I,j。

  R指令通常用于算术和逻辑运算,它包含用于读写数据的寄存器的地址。如果是逻辑位移运算,那么位移运算的位移会跟随,当前面的操作码不足时,最后一个功能码会指示对应的具体指令。

  I指令,通常用于数据传输、条件分支以及not运算中使用变量或常量的时候。此时没有位移和操作码,也没有第三个寄存器。相反,这三部分直接组合成一个地址值或常数。

  J指令实际上是跳转指令,高6位以外的26位是跳转后的地址。

  Add $t 0,$s2,$s1让我以一个简单的加法算术指令add t 0,t0,t0,s2,$s1为例。为了方便,下面我们都用十进制来表示对应的代码。

  在对应的MIPS指令中,opcode为0,rs表示第一个寄存器s1的地址为17,rt表示第二个寄存器,s2为18,rd表示目标临时寄存器t0的地址,为8。因为不是位移操作,所以位移为0。把这些数字拼在一起就成了MIPS的加法指令。

  为了方便阅读,我们通常用十六进制来表示相应的二进制数。在这里,即0x02324020。该编号也是该指令对应的机器代码。

  让我们回到开头谈到的穿孔带。如果我们对1使用打孔,对0使用不打孔,对一条打孔纸带的命令使用4行8列,那么这条命令可能如下所示:

  恭喜你。看完这些,你应该已经学会了如何作为人肉编译器和汇编器对纸带进行编程。不用对用过打卡的yydsb顶礼膜拜。

  总结到这里,我想你也明白了,这个讲座开头提到的穿孔卡,其实就是一种存储程序计算机。

  只是整个程序的机器码,不是计算机编译的,而是程序员用人脑“编译”成卡片的。相应的程序不存储在设备中,而是作为穿孔卡片存储。但是整个程序的逻辑和其他CPU的机器语言没什么区别。它只处理一串“0”和“1”的机器代码。

  在这个讲座中,我们看到了一个C语言程序是如何被编译成汇编语言,甚至通过汇编程序翻译成机器码的。

  除了C之类的编译语言,无论是Python之类的解释语言,还是Java之类的使用虚拟机的语言,其实到最后,所有不同形式的程序都是把我们写的代码转换成CPU可以理解的机器代码。

  只有解释性语言是在程序运行时由解释器逐句翻译的,而Java这种使用虚拟机的语言是由虚拟机实时解释或编译成机器码最终执行的。

  但是,仅仅了解一条指令是如何变成机器代码的,肯定是不够的。在接下来的几节中,我将深入解释包括条件、循环、函数和递归在内的完整程序是如何在CPU中执行的。

  考虑在命令行上打印一个数字。背后对应的机器码是什么?你可以试着通过GCC输入这个的汇编代码和机器码。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: