算术操作
一些指令类
每一个指令类都有各种不同大小操作数的变种(除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第三章之算术指令内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复