浏览 2965 次
锁定老帖子 主题:C语言位移运算的编译
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-10-25
位运算是底层开发中常用的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位数据位移的时钟周期数的两倍。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |