char类型转数据int类型,前面补0还是补1

在写Qt读PE文件的2进制编码时遇到,将PE文件读到QByteArray中,根据PE文件的e_lfanew,来定位PE文件标识“PE”。

QByteArray中存储一个字节为0x80,将QByteArray对象arr加下标强转为Int,得到的却是-128。

上恕问题简化来看:

第一次打印,用QByteArray强转了一下。

第二次打印,直接强转的0x80。

结果却是很神奇, 第一次是-128,第二次是128。

按常理来说,一个数据在内存中的存储不存在是不是带符号数据,而取决于你拿到这个数据后要解析成什么类型的数据来用。

问了一下同事,经过他反复尝试发现,先将arr[0]转成  unsigned char 再转成 int 。

结果这次非常神奇,竟然都是128了。为什么会发生这种情况呢?

难道数据转换之前,还有其他操作吗?

于是我将他们的二进制打印了出来。

发现如果如果arr[0]直接转int的话,前面会全部补1。

切换到宇宙第一IDE

先看将0x80存到char中,直接用int或上

结果负的128。查看代码反汇编

发现了一条操作 movsx 

我们再看 0x80存放到 unsigned char ,再用int或上

运行结果正128。再看反汇编

发现,movsx  变成了movzx

这两条指令是什么意思呢,通过x86汇编指令手册描述

movsx 是将高位扩展成符号位

movzx 是将高位扩展成0

破案了,所以用char来强转int,如果符号位为1,就会将所有的高位全部补成1。

我们来调试一下看看

先将0x7F (二进制:0111 1111)符号位为0。看看movsx会怎么处理

先将7f放到c的栈区,再将c栈区的值也就是0x7F movsx 到eax寄存器

此时EAX寄存器的值为 0000007F。

再将0x80 (二进制:1000 0000)符号位为1。看看movsx会怎么处理

此时EAX寄存器的值为 FFFFFF80。

自此真相大白,所以当需要char 转 int的时候,还是先将char 转成 unsigned char后再转为int才比较保险。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值