C语言位移运算的编译

  位运算是底层开发中常用的C语言运算,移位运算是相当有用的一种运算。举例说明:

 

int main() {
	long a;
	long b = a << 16;
	long long c;
	long long d = c << 16;
	return 0;
}

  在这里写了两种位移运算,是比较典型的,一种是32位长度数据的位移,另一种是64位长度数据的位移。由于x86架构的计算机寄存器长度为32,因此64位的数据位移操作怎样在32位长的寄存器上完成呢?

 

main:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	andl	$-8, %esp //内存对齐(由于存在64位长度的栈数据)
	subl	$32, %esp
	movl	28(%esp), %eax //变量a读入寄存器eax,时钟周期数4
	sall	$16, %eax //一条位移指令就解决了位移,$16是立即数,时钟周期数3
	movl	%eax, 24(%esp) //写回变量b,时钟周期数2
	movl	16(%esp), %eax //这里是变量c的低32位,时钟周期数4
	movl	20(%esp), %edx //这里是变量c的高32位,时钟周期数4
	shldl	$16, %eax, %edx //双精度位移,时钟周期数3
	sall	$16, %eax //普通位移,时钟周期数3
	movl	%eax, 8(%esp) //写回变量d低32位,时钟周期数2
	movl	%edx, 12(%esp) //写回变量d高32位,时钟周期数2
	movl	$0, %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc

 

  这里有一个比较特殊的指令shld,是双精度位移指令,这条指令会将低32位与高32位同时进行左移操作,低32位移出的部分会自动填充到高32位中去,完成以后低32位会被还原为移位以前的状态。因此在完成双精度位移以后,还需要再对低32位进行一次位移才能够满足要求。

 

  在x86体系下,完成C语言64位数据位移的时钟周期数恰好是32位数据位移的时钟周期数的两倍。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值