我是靠谱客的博主 简单绿茶,最近开发中收集的这篇文章主要介绍CSAPP第三章程序的机器级表示程序的机器级表示:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

程序的机器级表示:

程序编码:

数据格式:

访问信息

寄存器:

操作数:

数据传送指令:

数据传送示例

导入和弹出栈数据:

算术和逻辑操作:

加载有效地址(leaq):

一元和二元操作:

移位操作:

特殊的算术操作:

控制:


程序的机器级表示:

程序编码:

C语言 ---【预处理器---> 扩展后的C ---【编译器】---> 汇编语言 ---【汇编器】---> 二进制目标文件  ---【链接器】---> 可执行文件

 

对于机器级编程的两种抽象:

  1. 指令集架构将程序的行为抽象成每条指令按顺序执行
  2. 内存模型抽象成非常大的字节数组

 

机器代码可见的处理器状态:

程序计数器、整数寄存器、条件码寄存器、向量寄存器

 

数据格式:

字表示16位,32位双字,64位四子,不同数据类型大小不同,汇编后缀也不同

64位机器里面一个指针8个字节

访问信息

寄存器

一个X86-64的cpu包含一组16个存储64位值的通用目的寄存器:

  1. 部分指令会在寄存器中生成小于8个字节的指令,生成1个字节、2个字节的指令会保持剩下的字节不变,生成4字节数字的指令会把高位4个字节置为0。

 

操作数:

一个指令有>=1个操作数.

三种类型:立即数、寄存器、内存引用

 

  1. 寄存器用类似数组的R[r]来表示,寄存器名就是索引,R[r]表示寄存器存储的值
  2. %rax是表示寄存器里存的值0x100,(%rax)表示内存里0x100位置处的值。
  3. 64位机器里不能用32位寄存器来寻址:(%ebx)非法

数据传送指令:

MOV  S,D

前面是源操作数:立即数,寄存器里的值,内存里的值

源操作数表示的是如果源操作数为%rax,表示寄存器里的值,如果源操作数为(%rax),表示间接寻址内存里的值

 

后面是目标操作数:寄存器、内存地址

后面是存储数据的位置,如果目标操作数为%rax,表示放到寄存器里,如果源操作数为(%rax),表示放到间接寻址后的内存地址里。

 

  1. Movb, movw, movl, movq表示对于操作数大小不同
  2. 不能将内存里的值直接传送到内存:mov (%rax),(%rbx) (非法)
  3. 一般情况下只会更新目的操作数指定的寄存器,唯一例外是movl,会把高位四字节记成0。见寄存器部分
  4. movq和movabsq区别,前者只能移动32位补码数字,然后符号扩展到64位的值,后者可以以任意64位立即数作为源操作数,并且目标只能是寄存器

 

MOVZ S,R

小移动到大时,零扩展

uploading.4e448015.gif转存失败重新上传取消

按照b,w,l,q应该有四个,为啥没有movlq,因为movlq的含义和movl的含义是一样的。

 

MOVS S,R

小移动到大时,符号扩展,高位由源操作数第一位复制得到

cltq的含义: movslq %eax, %rax

 

为啥都只考虑小移动到大,大会不会移动到小呢?

如果目标是内存地址,应该会以此地址为起始,往后存储,所以不存在源操作数过大

如果目前是寄存器呢,64位操作数移动到32位寄存器会发生什么?应该是低32位存储

 

数据传送示例

uploading.4e448015.gif转存失败重新上传取消

这段从C到汇编的转换,帮助我们理解了指针是什么:

  1. 指针在64位机器中,占8个字节,指针其实就是地址。
  2. 指针变量在右边时,意思是指针指向的内存里的,-> 对应于MOV指令中的源操作数,我们对(%rax)的理解
  3. 指针变量在右边时。意思是指针指向的内存。-> 对应于MOV指令中的目标操作数,我们对(%rax)的理解
  4. 在上图汇编中,把指针存在寄存器rdi里,2,3两点可以解释c语言和翻译成汇编后的含义是一致的

5、局部变量通常放在寄存器中,而不是内存,访问寄存器比内存快得多

 

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

再通过这个例子,我们可以认识一下&取址操作。&a的含义是取值为4的a变量他在内存中的地址。

 

导入和弹出栈数据:

栈是什么?栈不是什么神奇的东西,也就是内存中的某个区域。

 

栈指针,始终指向栈顶位置,入栈时地址减小:

uploading.4e448015.gif转存失败重新上传取消

1、pushq和popq都是可以用mov指令+计算指令替代的。区别在于前两个指令大小只有1个字节。

2、栈可以同样当做内存来处理:movq 8(%rsp), %rdx会将第二个四字从栈中复制到寄存器rdx,为什么是第二个四字?8(%rsp)操作数值为M[R[%rsp] + 8], 取的是栈顶上方8-15个字节,即第二个四字。

算术和逻辑操作:

uploading.4e448015.gif转存失败重新上传取消

加载有效地址(leaq):

  1. 源是内存地址(看上去是),目标是寄存器
  2. 和movq的区别:

Movq (%rdx) %rax 将M[R[rdx]]的值赋给rax

Leaq (%rdx) %rax 将R[rdx]的值赋给rax

  1. 由于这种特性,往往用于普通的算术操作:long t = x + 4y +12z

 

一元和二元操作:

uploading.4e448015.gif转存失败重新上传取消

  1. 一元操作:

只有一个操作数,这个操作数必须是寄存器或者内存(也就是必须是个地址

表示的含义是:把这个寄存器或者内存的值中,再放入这个寄存器或者内存中

  1. 二元操作:两个操作数,第一个操作数是源,可以是寄存器或者内存、立即数,这个操作数必须是寄存器或者内存(也就是必须是个地址

表示的含义是:把这个寄存器或者内存的中取出,和源操作数做计算,放入这个寄存器或者内存中

移位操作:

  1. 第一个数是移位量,第二个是目标操作数

表示的含义是:目标操作数的值经过移位处理后,放回目标操作数位置

  1. 移位量时立即数或者单字节寄存器cl
  2. 当移位量为cl时的移位规则是:对w位长的数据值进行操作,移位量由cl寄存器的低m位组成,2^m-1=w
  3. 左移指令SAL和SHL相同,右边补0
  4. 右移质量SAR执行算术右移(填符号位),SLR执行逻辑右移(填0)

 

特殊的算术操作:

uploading.4e448015.gif转存失败重新上传取消

此图的idivq和divq的寄存器有误,看原书第三版:

 

imulq的两种形式:

  • 二元操作:将两个64位相乘得到一个64位数,此时,仅用imulq一个操作可以同时实现有符号数和无符号数的乘法:截断后的补码的位级行为是一样的
  • 如上图中,只有一个操作数,将两个64位相乘得到一个128位数,分别放在两个寄存器中

 

控制:

除了整数寄存器,CPU还维护着一组单个位的访问条件码寄存器:他们记录了算术或逻辑操作的属性,我们检测这些寄存器的值,就可以判断条件的真假,就是这么神奇

uploading.4e448015.gif转存失败重新上传取消

举例而言,当我们执行一个ADD指令完成 t = a + b这个C表达式时,各个条件码寄存器都会发生变化:

uploading.4e448015.gif转存失败重新上传取消

ZF和SF很好理解,但是CF、OF是什么意思呢,我们可以举例说明:

CF可以使用反证法:如果没有无符号溢出,t必然大于a,反之亦然

OF:有符号数加法溢出,a和b必然符号不同,所以有(a<0 == b<0), 同时如果没有溢出,t必然和a、b符号相同。

uploading.4e448015.gif转存失败重新上传取消

最后

以上就是简单绿茶为你收集整理的CSAPP第三章程序的机器级表示程序的机器级表示:的全部内容,希望文章能够帮你解决CSAPP第三章程序的机器级表示程序的机器级表示:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部