CSAPP阅读笔记-汇编语言初探(算术和逻辑操作类指令)-来自第三章3.5的笔记-P128-P135
1.算术和逻辑操作类指令分四类:加载有效地址,一元操作,二元操作和移位,如下:

2. leaq指令,类似mov指令,它左侧的数看似是给出一个地址,在内存中从给定的地址取操作数,传给右边的目的地。但其实没有取,而是直接将左侧的数对应的地址传给了右侧的目的地。
例子: leaq 7(%rdx,%rdx,4),%rax
若%rdx的值为x,则最后%rax的值为5x+7,而不是以5x+7为地址,在内存中寻址得到的操作数
3. 第二组是一元指令,目的地为寄存器或一个内存位置,具体不用介绍,看表就好。
4. 第三组是二元指令,第二个操作数既是源又是目的,第一个操作数可以为立即数、寄存器或内存位置,第二个操作数可以为寄存器或内存位置。
5. 第四组是移位操作,第一个操作数是移位量,它可以是立即数或存放在%cl中,第二个操作数是要移位的数,可以是寄存器或者内存位置。当移位量存放在%cl中时,具体的移位量由移位指令的移位量级来决定,比如salb,此时23=8,则移位量由%cl的低3位决定,如%cl=0cFF,则移位量为7,同理,salw移15位,sall移31位,salq移63位。而决定移位指令的移位量级的则是被移位的数的量级,比如被移位的是%rax,则用salq。
左移指令有sal和shl,两者等价,移动后右边填0。右移指令有sar和shr,sar为算术移位,左补符号位,shr为逻辑移位,左补0。
练习:
xorq %rdx,%rdx
1.它做了什么?
答:它实现了对%rdx的置0
2.它有什么其它的汇编表达形式?
答:movq $0,%rdx
3.比较这两种操作分别编码的字节长度
答:xorq占3个字节,movq这里占7个字节,所以一般使用xorq来实现置0操作,由于任何更新低位4字节的指令都会把高位4字节置为0,
所以可以用 xorl %edx,%edx(2字节) 和 movl $0,edx(5字节)来实现。
6.特殊的算术操作
1.imulq,前面提到的imulq会从两个64位的操作数产生一个128位的操作数,截取其中的64位作为结果。此时需要两个操作数。
(注意,一个a位的操作数和一个b位的操作数,产生的乘积是a+b位的操作数)
2.此外,x86-64提供一系列单操作数指令,用于进行全128位运算
mulq是无符号乘法,imulq是补码乘法,它们都是单操作数指令,另一个操作数必须存在%rax中,乘积放在%rdx(高64位)和%rax(低64位)中。
测试:
#include <inttypes.h>
typedef unsigned __int128 uint128_t;
void store_uprod(uint128_t *dest,uint64_t x,uint64_t y)
{
*dest = x*(uint128_t)y;
}
此程序中,uint64_t类型由头文件inttypes.h定义,但此文件未定义128位的整数,因此使用gcc自带的unsigned __int128整数支持,为了和uint64_t保持一样的命名规律,用typedef声明成uint128_t。
其对应的汇编代码如下:
store_uprod:
movq %rsi,%rax
mulq %rdx
movq %rax,(%rdi)
movq %rdx,8(%rdi)
ret
这里把乘积的低8字节存在了%rdi寻址的内存地址,高8字节存在了更大的地址,所以这里是小端法存储。
3.同样的,也有对应的单操作数无符号除法(divq)和有符号除法(idivq),即128位除法,注意没有双操作数的除法。
它们把%rdx(高64位)和%rax(低64位)合起来的128位作为被除数,除数则作为单操作数被给出,结果的商存在%rax中,余数存在%rdx中。
但是,当要进行64位除法时,此时没有双操作数的除法,怎么办?
此时会把64位的被除数存在%rax中,%rdx被设置为全0(无符号运算)或%rax的符号位(有符号运算)。设置%rdx为%rax的符号位可以用指令cqto完成,
它不需要操作数,会自动读出%rax的符号位,并复制到%rdx的所有位。
完毕!
CSAPP阅读笔记-汇编语言初探(算术和逻辑操作类指令)-来自第三章3.5的笔记-P128-P135的更多相关文章
- CSAPP阅读笔记-汇编语言初探(数据传送类指令)-来自第三章3.2-3.3的笔记-P115-P128
1.如何由机器代码生成汇编代码? objdump -d再加上文件名即可直接在终端看到由反汇编器恢复的汇编代码.注意,文件名并不一定得是.o文件,任何可执行文件都可以. 结果如下: 仅列举了反汇编tes ...
- CSAPP阅读笔记-汇编语言初探(控制类指令)-来自第三章3.6的笔记-P135-P163
1.正溢出与负溢出: 首先,一个正数与一个负数相加,不可能溢出,因为结果的绝对值一定小于两个加数的绝对值,既然两个加数能合理表示出来,结果一定也能合理表示出来. 其次,正溢出是由于两个很大的正数相加, ...
- CSAPP阅读笔记-gcc常用参数初探-来自第三章3.2的笔记-P113
gcc是一种C编译器,这次我们根据书上的代码尝试着使用它. 使用之前,先补充前置知识.编译器将源代码转换为可执行代码的流程:首先,预处理器对源代码进行处理,将#define指定的宏进行替换,将#inc ...
- CSAPP阅读笔记-变长栈帧,缓冲区溢出攻击-来自第三章3.10的笔记-P192-P204
一.几个关于指针的小知识点: 1. malloc是在堆上动态分配内存,返回的是void *,使用时会配合显式/隐式类型转换,用完后需要用free手动释放. alloca是标准库函数,可以在栈上分配任 ...
- CSAPP阅读笔记-struct, union, 数据对齐-来自第三章3.9的笔记-P183-P191
1.数据对齐 为什么要对齐:通俗点解释就是CPU对数据访问时,每次都是取固定数量的字节数,假如一次取4个字节,若有个int存在0x01-0x04,则一次就能取出,若存在0x03-0x06,则需要分两次 ...
- CSAPP阅读笔记-数组分配与访问-来自第三章3.8的笔记-P176-P183
这一节比较简单,仅记录几个比较重要的点: 1.C语言允许对指针进行运算,计算出的值会根据该指针引用的数据类型大小进行伸缩. 例子: 其中,xE是数组的起始地址.注意,指针运算时,若最终结果为指针,则指 ...
- CSAPP阅读笔记-栈帧-来自第三章3.7的笔记-P164-P176
1.基本结构: 如上图所示,是通用的栈帧结构.大致分两块,调用者函数P和被调用者函数Q. 对P来说,要做的工作是把传递参数中多于6个的部分压栈,随后把Q返回时要执行的下一条指令的地址压栈. 对Q来说, ...
- CSAPP阅读笔记-32位64位的区别--来自第三章引言的笔记--P110
仅从寻址上看,32位和64位机器能寻址的内存空间大小不同. 需要知道的是,计算机系统对存储器作了抽象,程序“认为”内存是一个很大的字节数组,然而实际上它是由多个硬件存储器和操作系统组合起来实现的. 程 ...
- Java 螺纹第三版 第三章数据同步 读书笔记
多线程间共享数据问题 一.Synchronizedkeyword atomic一词与"原子"无关,它以前被觉得是物质的最小的单元,不能再被拆解成更小的部分. 当 ...
随机推荐
- 从jvm运行机制来分析 String对象负值
测试1: 代码 public class Test { public static void main(String[] args) { String s1="aaa"; f(s1 ...
- C/C++语言中指针数组和数组指针比较区别
指针数组:int *p[3] 定义一个指针数组,其中每个数组元素指向一个int型变量的地址 意思就是指针的数组,数组里面都是指针 例子: int *p[3];//定义了一个指针数组,有3个成员,每个成 ...
- 设计模式16:Mediator 中介者模式(行为型模式)
Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的 ...
- C++ springf()的用法(转)
转:http://blog.csdn.net/masikkk/article/details/5634886 在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望.由于sprin ...
- linux bash命令行基本操作
shell shell 我们叫做壳,我们知道操作系统底层是有一个内核kernel的,内核用来实现所有上层服务,所有上层命令,上层应用所需要的一些基本功能,比如说网络连接,网络通信,比如说键盘驱动, ...
- 获取hyper-v和vmware虚机状态
在vmware的PowerCLI和微软的scvmm的PowerShell中可以通过Get-VM命令来获取虚拟机的信息.下面我们用代码的方式去实现,代码相关类方法就是对命令的封装. vmware api ...
- C# 数字转换成汉字大写 数值转换成汉字大写
1.数字转换成汉字大写 public string NumToChinese(string x) { //数字转换为中文后的数组 //转载请注明来自 http://www.shang11.com st ...
- ASP.NET MVC实现一个用户只能登录一次 单用户登录
现在许多网站都要求登录后才能进行进一步的操作,当不允许多用户同时登录一个帐号时,就需要一种机制,当再登录一个相同的帐号时,前面登录的人被挤下线,或者禁止后面的人登录.这里实现的是前一种功能. 网上有许 ...
- Android 开发怎样做代码加密或混淆?
欢迎访问网易云社区,了解更多网易技术产品运营经验. 在大公司怎么做android代码混淆的?发现他们的软件用apktool反编译居然没看到classes.dex文件和当前安卓APP加固到底该如何做到防 ...
- 【04】循序渐进学 docker:Dockerfile
写在前面的话 从前面我们简单的了解了镜像,也运行了容器,各种官方的镜像显然无法满足我们自己的需求,我们目的终究是运行自己的业务. 所以,本章节的 Dockerfile 就主要讲怎么在官方镜像的基础上制 ...