深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符

本文转载地址:http://www.cnblogs.com/zuoxiaolong/p/computer14.html

引言

  本文的内容其实可以成为汇编语言的基础,因为汇编语言大部分时候是在操作一些我们平时开发看不到的东西,因此本文的目的就是搞清楚,汇编语言都是在操作些什么东西。或者更准确的说,各种汇编指令都是在操作什么样的对象。

汇编层次的对象

  在平时的开发过程中,CPU处理器的状态对开发者是隐藏的,我们看不到CPU当中各个对象的状态。但是在汇编语言中,我们可以清楚的看到这些对象的状态,其中CPU主要包含以下几个对象。

  程序计数器(PC):记录下一条指令的地址。

  整数寄存器文件:共8个,可以存储一些地址或者整数的数据。

  条件寄存器:保存算数或逻辑指令的状态信息,可以实现程序的流程控制。

  浮点寄存器:存储浮点数。

  可以看出,这些都是CPU处理器当中的对象,上一章我们写过一个简单的C程序,相信如果不是看了汇编代码,各位也都看不出来在程序运行过程中,CPU当中这些对象都在做着一些什么样的操作,又在存储着一些什么样的内容。

数据的格式

  在上一章当中,几乎所有的汇编指令后面都有一个字母l,比如movl、addl、subl、pushl等等,这个l的后缀其实就是表示的数据格式,表示我们操作的是32位的数值。

  在计算机从16位扩展到32位,以至于当前的64位来讲,数据格式就一直在变。但是历史总会多少影响着未来的走向,因此我们习惯称16位为“字”,而32位则为“双字”,相应的,64位则为“四字”。

  以下我们以IA32架构为例,来看一下各个数据格式对应的后缀是什么。

  图当中已经介绍的比较清楚,LZ这里就不再废话了。需要一提的就是,long long int在IA32架构中是不支持这种数据格式的,因此就没有列出它的后缀。另外,long double是一种扩展类型,通常采用12个字节来表示。

  上面的图示使用的方式很简单,比如mov指令,它是一个数据传送的指令,那么movb就代表传送一个字节的数据,movw就代表传送两个字节的数据,而movl就代表传送四个字节的数据。

寄存器

  寄存器是CPU当中非常重要的对象,一般情况下,很多临时变量都会存储在这里,就像上一章当中的临时变量t,在优化之后,t将不再进入主存,而只留在寄存器当中。这样可以提高程序运行的速度,因为寄存器的速度要高于主存,而且在寄存器与主存之间传输数据,也是十分耗时间的一件事。

  下面是一张书中的寄存器图示,它基于IA32架构给出。

  可以看到,对于%esp和%ebp寄存器来讲,图中标注了它们分别是栈指针以及帧指针。而对于另外六个寄存器来讲,它们大部分时候是一样的,但是还是有些许的不同。

  比如%eax寄存器,它很多时候用来存储函数的返回值。而对于%eax、%ecx、%edx、%ebx来讲,它们都可以被访问单独的字节。另外需要一提的是,这八个寄存器都可以被访问双字节。

  除了以上的区别之外,对于%eax、%ecx、%edx和%ebx、%esi、%edi来讲,它们的使用惯例也有些许不同,这个在后面我们将深入讨论。这里各位只要大概认识一下这八位神仙就行了。

操作数指示符

  操作数指示符这个称谓是书上给的,但LZ觉得这个概念不太容易理解,操作数指示符其实指的就是一种取值的标识方式,用来获取参与各种操作的操作数。

  这些标识方式一共有三种,一种是$符号后跟一个标准C表示的整数,比如$100,$0x11等等。第二种则是寄存器,当它作为一个操作数的时候,则是取的寄存器当中的数值。另外,对于寄存器来说,也可以选择性的操作4个、2个、1个字节,而并不一定非要操作4个字节。最后一种,则是我们相对来说最熟悉的,就是存储器或者说内存。当它作为一个操作数的时候,会去计算存储器地址的数值,然后去这个地址取相应的数值。

  对于这三种操作数的标识方式,在书中给出了一个表格,这里LZ贴一下。

  第一列是代表的类型,而第一行则是指的立即数,第二行则是指的寄存器,而剩下的都是存储器了。对于立即数和寄存器来讲,比较好理解,就是直接取值或者取寄存器的值。而对于存储器来讲,则有很多种情况,不过我们也可以看出,上面所有的情况,其实都是最后一种的特殊情况。Imm(Eb,Ei,s)是存储器取值的一般形式,比如当Imm为0时,则是倒数第二种取值方式。对于其它的形式,也可以使用同样的方式推算出来。

  由于存储器相对来说,理解起来比较困难一点。因此这里LZ举个简单的例子,比如对于4(%esp,%eax,4)这个操作数来讲,它代表的是内存地址为4+%esp+4*%eax的存储器区域的值。

  操作数是大部分指令都有的,因此上面的这些标识方式,在之后的文章中我们会经常看到,它们将会成为各位猿友很好的朋友。

文章小结

  本章只介绍了一些汇编当中基础的知识,这些内容相对来讲不是特别困难,但却是打开后面神秘大门的钥匙。因此倘若有哪位猿友不是太理解本章的内容的话,LZ希望各位可以从实践入手去理解一下本章的内容。这一点可以结合上一章来看,从上一章给出的汇编代码中寻找数据格式、操作数以及寄存器的部分,这应该是十分轻松的,因为上一章的汇编代码中充斥着这三个部分的内容。

版权声明


作者:zuoxiaolong(左潇龙)

出处:博客园左潇龙的技术博客--http://www.cnblogs.com/zuoxiaolong

您的支持是对博主最大的鼓励,感谢您的认真阅读。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我的技术专栏

C++设计模式:Template Method

1103
来自专栏佳爷的后花媛

h文件和c文件的区别include本身只是一个简单的文件包含预处理命令,即为把include的后面文件放到这条命令这里,除此之外,没有其它的用处(至少我也样认为).

其实在H文件里写函数也无所谓,只是不符合习惯而已。只要按照以上的格式写,一个H文件添加多少次都无所谓,

2272
来自专栏xingoo, 一个梦想做发明家的程序员

《深入浅出Nodejs》—— 读后总结

这一个月过去了三分之二,加上之前看过这本书三分之一,这才算是看完。 虽然看完一遍,但是这本书内容很深,以后肯定是还要继续翻阅的..... 什么是Node...

1925
来自专栏有趣的django

1.python简介

简介 1、python语言介绍 python的创始人:Guido Van Rossum 2、python是一门什么样的语言 编程语言主要从以下几个角度进行分类:...

3955
来自专栏java一日一条

java提高篇之异常(上)

在这个世界不可能存在完美的东西,不管完美的思维有多么缜密,细心,我们都不可能考虑所有的因素,这就是所谓的智者千虑必有一失。同样的道理,计算机的世界也是不完美的,...

982
来自专栏xcywt

关于非局部跳转

  在看《程序员的自我修养》时看到一个以前没见过的东西,为此记录下来。(当然事后才知道原来早就被人写烂了,啊哈哈哈)   非局部跳转在C语言中是一个备受争议的机...

19610
来自专栏海说

深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符

  本文的内容其实可以成为汇编语言的基础,因为汇编语言大部分时候是在操作一些我们平时开发看不到的东西,因此本文的目的就是搞清楚,汇编语言都是在操作些什么东西。或...

1304
来自专栏别先生

Javascript创建对象的学习和使用

1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>javascript对象的学习</title> ...

2029
来自专栏java一日一条

Java异常有多慢?

实际上,真正要讨论的问题并不是,“相对‘那些不会发生错误的代码’来说,‘那些以异常形式上报的错误’会有多慢?”,因为你可能也认同“已接受的回答”。相反,真正的问...

3452
来自专栏数据和云

巧用SQL:Oracle中实现split相关方法总结

尚世波 从事数据库方面工作多年,专注于pl/sql开发、数据库设计、优化方面的研究,喜欢挑战 前文回顾:巧用SQL:oracle pl/sql split函...

3905

扫码关注云+社区

领取腾讯云代金券