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一词与"原子"无关,它以前被觉得是物质的最小的单元,不能再被拆解成更小的部分. 当 ...
随机推荐
- 编写高质量代码改善C#程序的157个建议——建议77: 正确停止线程
建议77: 正确停止线程 开发者总尝试对自己的代码有更多的控制.例如,“让那个还在工作的线程马上停止下来”.然而,并非我们想怎样就可以怎样的,这至少涉及两个问题. 第一个问题 正如线程不能立即启动一样 ...
- 编写高质量代码改善C#程序的157个建议——建议76: 警惕线程的优先级
建议76: 警惕线程的优先级 线程在C#中有5个优先级:Highest.AboveNormal.Normal.BelowNormal和Lowest.讲到线程的优先级,就会涉及线程的调度.Windows ...
- Ubuntu下使用UFW,以及CentOS7的默认防火墙firewalld
UFW是一个简化版的iptables,基于iptables,配置比iptables简单 默认UFW是关闭状态,即Ubuntu默认打开所有端口,比较危险. 检测状态 ufw status 设置默认状态, ...
- 从Entity Framework的实现方式来看DDD中的repository仓储模式运用
一:最普通的数据库操作 static void Main(string[] args) { using (SchoolDBEntities db = new SchoolDBEntities()) { ...
- eclipse可以调试但是无法打开网页,提示一直在加载
工作过程中遇到了eclipse调试可以正常执行,也没有报错,但是通过浏览器打开网页就是打不开,还提示一直加载.这个问题找了很多网页和搜索引擎,大多数的方法就是重新配置elipse里的tomcat的we ...
- ASP.NET Core入门(一)
大家好,很荣幸您点了开此篇文章,和我一起来学习ASP.NET Core,此篇文字为<ASP.NET Core入门>系列中的第一篇,本系列将以一个博客系统为例,从第一行代码,到系统发布上线( ...
- BAT 命令 .bat
echo.@.call.pause.rem(小技巧:用::代替rem)是批处理文件最常用的几个命令 echo 表示显示此命令后的字符 echo off 表示在此语句后所有运行的命令都不显示命令行本 ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- UDP与IP分片
一.引言  UDP是简单的面向数据报的运输层协议.UDP不提供可靠性:它负责把应用程序传给IP层的数据发送出去,不保证能导到目的地. 二.UDP首部  端口号表示发送进程和接受进程.由于IP层已经 ...
- JAVA将秒的总和转换成时分秒的格式
public static void main(String[] args) { String str = "221"; int seconds = Integer.parseIn ...