概述
算术操作
一些指令类
每一个指令类都有各种不同大小操作数的变种(除leaq
外)
指令 | 效果 | 描述 |
---|---|---|
leaq S, D | D<-&S | 加载有效地址 |
INC D | D<-D+1 | 加一 |
DEC D | D<-D-1 | 减一 |
NEG D | D<- -D | 取负 |
NOT D | D<-~D | 取反 |
ADD S, D | D<-D+S | 相加 |
SUB S, D | D<-D-S | 相减 |
IMUL S, D | D<-D×S | 相乘 |
XOR S, D | D<-D^S | 异或 |
OR S, D | D<-D|S | 或 |
AND S, D | D<-D&S | 与 |
SAL k, D | D<-D<<k | 左移 |
SHL k, D | D<-D<<k | 左移,等同于SAL |
SAR k, D | D<-D>>Ak | 算术右移 |
SHR k, D | D<-D>>LK | 逻辑右移(logic) |
- ATT格式的代码,操作数的顺序与一般的直觉相反
加载有效地址
leaq
其实是movq
指令的变形
它根本没有引用内存,而是直接将有效地址写入目的操作数
目的操作数必须是寄存器
它还可以简洁地描述普通的算术操作。
例如,当%rdx
值为x时,leaq 7(%rdx,%rdx, 4), %rax
是设置寄存器%rax
的值为5x+7(不理解)
一元操作与二元操作
一元操作:只有一个操作数,既是源也是目的
二元操作:第二个操作数既是源也是目的
移位操作
移位量可以是一个立即数,或者放在单字节寄存器%cl
中——移位指令只允许使用该寄存器作为操作数
移位量由%cl
的低位决定
左移指令有两个名字:SAL
与SHL
,两者相同
右移指令:SAR
(算术移位)与SHR
(逻辑移位)
移位操作的目的操作数可以是一个寄存器或者是一个内存位置
上述的大多数指令既可以用于有符号运算,也可以用于无符号运算
只有右移才有区分
通常,一个寄存器会存放多个值,还会在寄存器之间传送程序值
特殊的算术操作
两个64位的整数相乘需要128位来表示结果
乘除法分为有符号与无符号,例如imul
与idiv
一个特殊的指令:cqto
:转换为8字(16字节)
imul
的两种形式:
- 64位乘64位->64位,同时实现无符号乘法与补码乘法
- 计算两个64位值的全128位乘积:
mulq
与imulq
。要求必须有一个参数在%rax
种,另一个作为源操作数给出,结果放在%rdx
(高64位)与%rax
(低64位)中
汇编器能通过计算操作数的数目判断你运行的是哪一条指令
使用inttype.h
——GCC提供的128位整数支持定义128位数字
除法与取模操作用单操作数除法指令提供。
idivl
将寄存器%rdx
与%rax
中的128数作为被除数,将指令的操作数作为除数给出
商存储在%rax
中,余数存储在%rdx
中
有符号除法:%rax
全为符号位
无符号除法:%rax
全为0
最后
以上就是合适树叶为你收集整理的CSAPP第三章之算术指令的全部内容,希望文章能够帮你解决CSAPP第三章之算术指令所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复