【CSAPP 3.5】算术和逻辑操作


下表列出了 x86-64的一些整数和逻辑操作。大多数操作都分成了指令类,这些指令类有各自带不同大小操作数的变种(除了 leaq)。例如,指令 ADD4条加法指令组成: addbaddwaddladdq,分别是字节加法、字加法、双字加法、四字加法。以下操作被分为 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程序:

long scale(long x, long y, long z)
{
   
        long t = x + 4 * y + 12 * z;
        return t;
}

编译时,该函数的算术运算以3leaq指令实现。

[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
	.cfi_endproc
.LFE0:
	.size	scale, .-scale
	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
	.section	.note.GNU-stack,"",@progbits

第一个参数x保存在%rdi里,第二个参数y<

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值