读书笔记——《深入理解计算机系统》第三章_程序的机器级表示(一)

    前言:已经大四,没有去找工作,选择了保研,之所以这样选择,有三个原因,一、刚进校时,听说保研都是牛人才能行的事,所以一心努力保研;二、2008年开始,经济危机比较严重,工作不好找,虽然软件专业要找一份工作还是比较容易,但好工作的机会少了很多,再多学习几年,规避下风险;三、三年多的本科学习下来,虽然简历看起来还像回事,但内心很虚,感觉真才实学没多少,都是略懂皮毛,做了太多表面工作,没有特长,选择读研,希望在某一方面能够深入学习,不再流于肤浅,真正地学有所长。

 

      保研成功后,过了近一个月猪一样的生活,实在过得空虚,看到考研同学每天辛苦地备考,在暗自庆幸的同时,也意识到,保研给我节约了很大一笔时间,不应该把这段时间荒废了。于是找了谭师兄和梁老师,让他们给我指点一二。梁老师的建议很中肯,他说如果他现在是HR,他会只招本科生,而不是研究生,因为现在研究生的质量比本科生高不到哪里去,而且一把年纪了,本科生出来工作三年后经验什么的都要比研究生强多了,说不定很多本科生还会当研究生的思想导师。这个说法当然比较绝对,但是我认为还是很有道理,因此,他说,你如果去读研,就不要再像本科一样把自己定位为一个coder,而应该至少是去做一个提出解决方案的,具体的实现让下面的人去做。你可以发现很多好东西好的解决方案都是老外提出来的,为什么中国人只能锦上添花,那里因为我的的基础知识不够扎实,知识体系不够健全,连自己手中的计算机是怎么工作的都不知道,怎么能提出很好的解决方案呢。所以,对于大四这一年,他给我推荐了两本书,一本《深入理解计算机系统》,这本书很基础,但是覆盖面很全,可以帮助加深对计算机的理解,知道它底层是怎么工作的,健全计算机体系的知识,而不是只学一些编程技术之类的表相的东西,这样永远只会被别人牵着走;另外一本书是《Unix环境高级编程》,他说你以后是去做网络方面的东西,而网络是绝对离不开Unix,你把这本书的程序当模板背下来以后,第一、编程就不成问题,第二、可以对Unix有全面的了解。

 

      好记性不如烂笔头,看了书不能过了了事,遂做此读书笔记,仅为学习温习之用,高手勿笑:)

 

      前言啰嗦完毕,回归正文:

     

      3.3数据格式(记住)

  • 由于是从16位体系结构扩展成32位,intel用术语字(word)表示16位数据类型,因此32位为双字(double words),64位数为4字(quad words)。
  •  以下是比较容易模糊的数据类型大小:

          32位机上:float 4    long int 4   double 8    longlong 8    char* 4   unsigned long 4

          64位机上:float 4    long int 8   double 8    longlong 8    char* 8   unsigned long 8

          另外,GCC 用long double表示扩展精度(10字节),出于存储器性能考虑,会被存储为12字节

 

      3.4访问信息

  • 一个IA32 CPU包含一组8个存储32位值的寄存器,用以存整数数据和指针:eax,ecx,edx,ebx,esi,edi     esp,ebp。大多数情况下前六个都用作通用寄存器,eax,ecx,edx的存储和恢复惯例不同于ebx,edi,esi(前三者为被调用者保存,后三者为调用者保存,详见3.7.3);最后两个用于存储指针,由于在过处理中非常重要,分别指向栈帧的顶部和底部,必须保持。

       3.4.1操作数指示符(记住)

        大多数指令有一到多个操作数,操作数有三种:

           立即数:即常数值

           寄存器:表示某个寄存器内容

           存储器引用:根据计算出来的地址(通常称有效地址)访问某个存储器位置

       因此寻址方式也有多种,如:立即数寻址、寄存器寻址、绝对寻址、间接寻址、变址寻址、伸缩化  的变址寻址……

 

      3.4.2数据传送指令(记住)

       几个重要数据传送指令:mov族(之所以称这为族是因为mov指令还有很多兄弟指令如movb、movw、movsb、movzb,这是我个人对它们的称呼,便于记忆mov其他几个比较低调的兄弟)、pop、push。

 

      另,对于mov族,movb、movw自不必做过多解释,movsb、movzb分别为符号扩展、零扩

展,它们只拷贝一个字节,源操作数均为单字节,并设置目的操作数中其余的位,效果如下:

      初始假设:%dh=8D  %eax=98765432

      1   movb   %dh,%al       ;%eax=9876548D

      2   movsbl %dh,%eax    ;%eax=FFFFFF8D(目的操作数高24位设为源字节最高位,在这里为很显然为1,所以前24位为全F)

      3   movzbl %dh,%eax    ;%eax=0000008D(目的操作数高24位被设为0)

 

     对于pushl指令等价于:

          subl $4,%esp

          movl %ebp,(%esp)  //注意这里的括号引起的差别

 

      popl指令等价于:

           movl (%esp),%eax

           addl $4,%esp

 

      3.4.3数据传输实例(理解)

       /*******C代码**********/ int exchange(int *xp, int y){ int x = *xp; *xp = y; return x; } //*********汇编代码******/ //1 movl 8(%ebp),%eax Get xp //2 movl 12(%ebp),%edx Get y //3 movl (%eax),%ecx Get x at *xp //4 movl %edx,(%eax) Store y at *xp //5 movl %ecx,%eax Set x as return value

       通过汇编代码可以得到两点收获

              1、指针其实是地址,间接引用指针就是将该指针放在一个寄存器中 ,然后在间接存储器引

                   用中引用这个寄存器

              2、局部变量通常保存在寄存器中,而不是存储器(个人猜测应该是局部变量属于动态

                   分配,局部变量因此被动态置入寄存器,而非存储器)

       

        3.5算术和逻辑操作(看看便可,不必深究)

       这类操作符大致分为四个小类:

           1、加载有交地址(leal),通常用来执行简单算术操作,目前还不太懂这个与mov的区别

           2、一元或二元操作:incl  decl  negl  notl  addl  subl  imull  xorl  orl  andl

           3、移位操作 :sall==shll(填0)  sarl(算术右移,填符号位)  shrl(逻辑右移,填0)

           4、特殊算术操作:imull(有符号64位乘法)  mull(无符号64位乘法)  cltd(转换为四字)

                idivl(有符号除法)   divl(无符号除法)

   

   

 

 

你可能感兴趣的:(工作,unix,读书,存储,扩展,Exchange)