【C/C++】关于移位操作的一些自学小结
2021/11/19 14:09:56
本文主要是介绍【C/C++】关于移位操作的一些自学小结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1、常见的左移右移,以无符号整型为例
可以看到,打印16进制的x值,只有15个f,说明右移4位没问题,高位正常补0。左移同理。
其中show方法参考《深入理解计算机系统(第三版)》写的函数,打印目标地址的字节。(我是小端,所以最低有效字节0xff在最前面打印,最高位的0x0f在最后打印。)
同理,如果将x右移63位,会得到只剩一个1,验证也没毛病。
然后可以去看看右移63位的汇编的代码:
红框圈起来的关键部分:
move %rdi, %rax 将%rdi寄存器的值放到%rax中,%rdi一开始会保存第一个参数,%rax会保存返回值 shrq $63, %rax 将%rax中的值逻辑右移一个立即数63
2、超过数据位数的右移
将右移位数改为64后,会出现“循环位移”的现象(应该是这个名词吧?),下面讲述一下过程。
可以看出,当右移64位时,会警告右移数>=类型宽度,但是依然可以编译,得到右边的汇编代码。
movq %rdi, %rax 同上,第一个参数放到返回值 movl $64, %ecx 将立即数放到%ecx中 shrq %cl, %rax 将%rax中的值右移%cl中的值的位数
这边比较难理解的是第二三句,其中有两个点注意到了就不难了。
1、(参照《深入理解计算机系统(第三版)》131页移位操作)位移量可以是一个立即数,或者放在单字节寄存器%cl中(只允许这个特定的寄存器作为操作数)x86-64中,移位操作对w位长的数据值进行操作,位移量由%cl寄存器的低m位决定,这里2^m=w,高位被忽略。
2、%rcx是一个64位寄存器,而他的低32位计为%ecx,低16位计为%cx,低8位计为%cl。所以此处其实就是将64拷贝到%rcx的低32位上,并将高位清0。
综上两个点,这里uint64_t是64位无符号整型,2^6=64,m=6,因此由%cl中的值(64=1000000二进制),只能使用其中的6位000000位移,右移0位也就是原数字,可以跑一下代码看看效果。
可以看到跟我们的推论结果一致。
个人笔记,如有错误的地方,烦请指正。
这篇关于【C/C++】关于移位操作的一些自学小结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享