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

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

  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。

相关推荐
mmsx2 小时前
Android 安全校验下沉到原生层:防 patch 与构建期自动化
android·安全·自动化
上海广测检测科技有限公司2 小时前
无线鼠标出口欧盟CE认证准备要点:RED指令下的射频、安全与电池义务梳理
经验分享·安全
INGNIGHT2 小时前
815 · 课程表IV(dfs)
算法·深度优先
QZ166560951592 小时前
可视化易用·低误报率·跨区域部署:知源-AI数据分类分级系统在金融行业的落地实践
大数据·网络·安全·网络安全
Pniubi2 小时前
力扣146.LRU缓存机制
算法·leetcode·缓存
云上工程笔记2 小时前
2026年7B到67B模型训练与推理GPU配置评测:LoRA、量化与全量微调对比
人工智能·算法·机器学习
softlgh2 小时前
鼾声识别:嵌入式离线鼾声检测 SDK 与睡眠健康数据
算法·智能家居·智能音箱·鼾声识别·智能枕头·打呼噜
了了2 小时前
图搜索基础学习笔记
算法
dk_tjy3 小时前
端点安全一体化系统技术解析:从架构设计到数据防泄密的落地实践
安全