2.数据传送指令

系列文章目录

程序的机器级表示:
CSAPP第三章的目录

  1. 历史观点
  2. 程序编码
  3. 数据格式
  4. 访问信息
  5. 算数和逻辑操作
  6. 控制
  7. 过程
  8. 数组分配和访问
  9. 异质的数据结构
  10. 在机器级程序中奖控制与数据结合起来
  11. 浮点代码

九曲阑干的课程目录:

  1. 机器级代码(至书的3.4.1)
  2. 数据传送指令(至书的3.5.4)
  3. 条件码寄存器
  4. 跳转指令以及bomblab_ev
  5. 过程
  6. 多维数组与结构体
  7. 缓冲区溢出

提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


参考

这里将参考列出来:

  1. CSAPP重点解读
  2. 九曲阑干
  3. 2015 CMU 15-213 CSAPP 深入理解计算机系统 课程视频
  4. 《深入理解计算机系统(CSAPP)》全书学习笔记(详细)

一、数据传送指令(Data Movement Instruction)

在这里插入图片描述

这里要注意:你要想将一个内存地址搬到另一个内存地址中去,不能用一条指令去完成。也就是mov (%rax) (%rbx)这条指令是错误的!!!
应该这样:
在这里插入图片描述可以这样来理解:
在这里插入图片描述

看一下几个mov指令的例子:
在这里插入图片描述

1.1 详细说明

例如,假设我们有一个寄存器 %rax,如果我们说:寄存器值:

  • %rax 中的值是 0x100。
  • 内存地址 0x100 的值为 0xAB
mov %rax, %rbx  ;%rax 寄存器中的值 (0x100) 复制到 %rbx 寄存器%rbx 现在也是 0x100
mov $0x1, (%rax)  ; 把数值 0x1 存储到内存地址 %rax 指向的位置(即内存地址 0x100
mov (%rax), %rbx  ; 从内存地址 0x100 读取数据,即 0xAB,并将这个值存储到 %rbx

(%rax)有点像指针解引用,就这么理解会很快地读懂

1.2 C语言和汇编的例子

在这里插入图片描述

在这里插入图片描述

1.3 源操作数向目的操作数扩展

  1. 零扩展
    在这里插入图片描述

这个类似于无符号数中short类型向int类型转换发生零扩展

  1. 符号扩展
    在这里插入图片描述

这个类似于有符号数short类型向int类型转化会发生符号扩展

  1. 特殊情况
    详情见PPT,挺难记住的。记住要查指令手册!!!作为教学内容,我们只需要记住原理就行了。

二、压入和弹出栈数据(Stack)

栈作为基本的数据结构这里不过多赘述。

我们这里讲的栈是系统运行时栈,本质上是操作系统中的内存的一块空间

在这里插入图片描述
栈的生长方向是从高地址到低地址,与之相反的则是堆。

2.1 push和pop操作

在这里插入图片描述

三、算数和逻辑操作

3.1 加载有效地址

在这里插入图片描述leaq 实际上是 movq 指令的变形。操作是从内存读数据地址到寄存器。
leaq 在实际应用中常常不用来取地址,而用来计算加法和有限形式的乘法

leaq 9(rdi, rsi, 4), rax;
//x in rdi,y in rsi。此操作实际上等于将 x+4*y+9 的结果存入 rax

来看一个例子:
在这里插入图片描述
解释:
在这里插入图片描述那为什么不直接用最下面的一条呢?直接让s=12?

这里要注意:在上一章文章中讲过s只能等于[1, 2, 4, 8],是因为变量寻址针对的是数组

通过上面的分析我们发现,它没有访问内存!!! 由于 LEAQ 可以在不访问内存的情况下执行运算,因此在某些情况下可以作为优化工具使用。

3.2 Unary Operation(一元操作)

只有一个操作数,这种操作数,它既是目的操作数,又是源操作数。
在这里插入图片描述

3.3 Binary Operations(二元操作数)

上面三个是算数操作,下面三个是逻辑操作
在这里插入图片描述
原内存:
在这里插入图片描述

操作后的内存:在这里插入图片描述

3.4 Shift Operations(移位)

第一项是移位量,然后第二项是要移位的数
在这里插入图片描述

3.4.1 移位量 Shift Amount

移位操作的移位量可以是:

  1. 一个立即数
  2. 放在单字节寄存器 %cl 中。该寄存器长度是8bit(0~255)

在这里插入图片描述
在这里插入图片描述
怎么理解上面的事情呢?
原书给出的解释:
在这里插入图片描述说实话这个解释比较弯弯绕,他其实就是取模的一个操作。

在汇编语言中,使用 %cl 寄存器作为移位量时,实际的移位数是 %cl 的值对某个数取模(取余数)的结果。这是为了防止移位数超过操作数的位数,这里的操作数位数指的是你要操作的数据的大小(如8位、16位、32位或64位)。在32位系统中,如果使用 %cl 寄存器作为移位数,并对一个32位寄存器如 %eax 进行操作,移位数的有效范围是0到31位。如果 %cl 的值超过了31,那么实际的移位数将是 %cl % 32。同理,在64位系统中,对于64位寄存器如 %rax,有效的移位范围是0到63位,如果超出则取 %cl % 64

让我们通过一个具体的例子来说明这一点:

假设 %cl 寄存器的值为 100,我们想在32位系统中对 %eax 寄存器进行左移操作。正常情况下,我们不能直接移动100位,因为这超出了 %eax 寄存器的最大位数(32位)。因此,实际的移位数将是 100 % 32 = 4

这里是具体的汇编代码示例:

mov $100, %ecx  ; 将100移入cl寄存器,注意cl是ecx的低8位
mov $1, %eax    ; 假设eax初始值为1
shl %cl, %eax   ; 左移cl指定的位数,即左移4位(100 % 32)

在这个例子中,%eax 寄存器原始的值是 1(二进制为 0000 0001)。经过左移4位操作后,%eax 寄存器的值变为 0001 0000,即十六进制的 0x10

通过这个例子,你可以看到 %cl 中的移位数如果超出了操作数的最大位数,实际执行的移位数是取模后的结果。这样的设计可以防止不必要的错误和异常行为,确保汇编指令的有效和安全执行。

3.5 不常见的特殊指令

在这里插入图片描述这个完全没必要记住,要用的时候查手册就行了

3.6 例子

知道怎么写下面这个例子,就代表这小节内容掌握得差不多了
在这里插入图片描述


总结

  1. 操作 源操作数 目的操作数
  2. 数据传送指令
  3. 压栈入栈指令,%rsp栈顶指针存放的寄存器
  4. 算数逻辑操作:
    • 一元操作
    • 二元操作
    • 逻辑操作
    • 移位操作
    • 特殊操作

查看:有道云笔记
内容:
在这里插入图片描述
在这里插入图片描述

  • 38
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值