位运算揭秘:左右移与符号位陷阱

二进制数据的运算成为位运算。操作符如下:

  1. "<<":左移运算,最高位左移到cf中,最低位为0。
  2. ">>":右移运算,最高位不变,最低位右移到cf中。
  3. "|":位或运算,在两个数的相同位上,只要有一个1,则结果为1。
  4. "&":位与运算,在两个数的相同位上,只有同时为1时,结果为1。
  5. "^":异或运算,在两个数的相同位上,当两个值相同为0,不同为1。
  6. "~":取反运算,将操作数每一位上的1变0,0变1。

代码

#include <stdio.h>

int main(int argc, char* argv\[\]){

argc = argc << 3;

argc = argc >> 5;

argc = argc | 0xffff0000;

argc = argc & 0x0000ffff;

argc = argc ^ 0xffff0000;

argc = ~argc;

unsigned int n = argc;

n <<= 3;

n >>= 5;

return 0;

}

这个是把无符号和有符号混在一起了

汇编

msvc

main(int, char**):

push %rbp

mov %rsp,%rbp

sub $0x30,%rsp

mov %ecx,0x10(%rbp)

mov %rdx,0x18(%rbp)

call 0x7ff746251817 ; <__main> shll $0x3,0x10(%rbp)

sarl $0x5,0x10(%rbp)

mov 0x10(%rbp),%eax

or $0xffff0000,%eax

mov %eax,0x10(%rbp)

andl $0xffff,0x10(%rbp)

mov 0x10(%rbp),%eax

xor $0xffff0000,%eax

mov %eax,0x10(%rbp)

notl 0x10(%rbp)

mov 0x10(%rbp),%eax

mov %eax,-0x4(%rbp)

shll $0x3,-0x4(%rbp)

shrl $0x5,-0x4(%rbp)

mov $0x0,%eax

add $0x30,%rsp

pop %rbp

ret

其他的编译器类似这个没有什么优化操作。在此只需要注意,右移运算有变化有符号数对应的指令为sar,可以保留符号位;无符号数不需要符号位,所以直接使用shr将最高位补0。

相关推荐
ppo_wu2 小时前
解决夸克网盘自动修改PDF打开方式的方法
经验分享·安全·网络安全
apcipot_rain3 小时前
C++转Java日记(03)
java·开发语言·c++
布莱克6053 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
xys_6784 小时前
深挖C++:类和对象(中)
开发语言·c++
D e re k ZH6 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
石小石Orz7 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
迪康coolmu7 小时前
出差终端数据安全落地实战:基于迪康端点安全一体化管理系统的四道防线实践
运维·服务器·经验分享·笔记·其他·安全·php
xiaoye-duck7 小时前
《C++ 项目:手写大模型接入 SDK》Ollama接口设计(上):初始化、全量响应实现和测试
开发语言·网络·c++·语言模型
zaizai10078 小时前
【Effective Modern C++】学习第一章
c++