下表列出了
x86-64
的一些整数和逻辑操作。大多数操作都分成了指令类,这些指令类有各自带不同大小操作数的变种(除了
leaq
)。例如,指令
ADD
由
4
条加法指令组成:
addb
、
addw
、
addl
、
addq
,分别是字节加法、字加法、双字加法、四字加法。以下操作被分为
4
组:
加载有效地址、
一元操作、
二元操作、
移位。
指令 | 效果 | 描述 |
---|---|---|
leaq S, D |
&S -> D |
加载有效地址 |
INC D |
D + 1 -> D |
加1
|
DEC D |
D - 1 -> D |
减1
|
NEG D |
-D -> D |
取负 |
NOT D |
~D -> D |
取反/取补 |
ADD S, D |
D + S -> D |
加 |
SUB S, D |
D - S -> D |
减 |
IMUL S, D |
D * S -> D |
乘 |
XOR S, D |
D ^ S -> D |
异或 |
OR S, D |
`D | S -> D` |
AND S, D |
D & S -> D |
与 |
SAL k, D |
D << k -> D |
左移 |
SHL k, D |
D << k -> D |
左移,等同于SAL
|
SAR k, D |
D >> k -> D |
算术右移 |
SHR k, D |
D >> k -> D |
逻辑右移 |
1. 加载有效地址
leaq
实际上是movq
指令的变形。它的指令形式是从内存读数据到寄存器,但实际上它根本就没有引用内存。它的第一个操作数看上去是一个内存引用,但该指令并不是从指定的位置读入数据,而是将有效地址写入到目的操作数。这条指令可以为后面的内存引用产生指针。它还可以简洁地描述普通的算术操作。例如,如果寄存器%rdx
地值为x
,那么指令leaq 7(%rdx, %rdx, 4), %rax
将寄存器%rax
设置为5x + 7
。目的操作数必须是一个寄存器。
看下面这个C
程序:文章来源:https://www.toymoban.com/news/detail-438559.html
long scale(long x, long y, long z)
{
long t = x + 4 * y + 12 * z;
return t;
}
编译时,该函数的算术运算以3
条leaq
指令实现。文章来源地址https://www.toymoban.com/news/detail-438559.html
[root@localhost2 3]# gcc scale.c -S -Og
[root@localhost2 3]# cat scale.s
.file "scale.c"
.text
.globl scale
.type scale, @function
scale:
.LFB0:
.cfi_startproc
leaq (%rdi,%rsi,4), %rcx
leaq (%rdx,%rdx,2), %rax
salq $2, %rax
addq %rcx, %rax
ret
.
到了这里,关于【CSAPP 3.5】算术和逻辑操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!