不要小看 b=~a>>4

问题的提出:

unsigned char a=0xA5;

unsigned char b=~a>>4;

注意~优先级高于>>,按照逻辑b应该为0x05

而结果b=0xf5,有点不符合逻辑,反编译(VC6,32位)看了一下,发现编译器把上面的代码编译成

mov ecx, dword ptr[ebp-8] ;ecx = 0xcccccca5

and ecx, 0ffh ;ecx = 0x000000a5

not ecx ;ecx = 0xffffff5a

sar ecx, 4 ;ecx = 0xfffffff5(注意移位后用1补齐!!!)

mov byte ptr [ebp-10h], cl ;cl = 0xfff5

反思一下,为了完成b=~a>>4,编译器做了三个工作

(1)申请了一个32位的临时变量x,将a扩展后,存入x

(2)将x取反

(3)将x右移4位,并将移位后x的低8位送给b

在第一步中,存在一个是否按符号位扩展的问题,这里a为unsigned型,不需要扩展,所以x = 0x000000a5;

若a为(signed) char型,则按符号位扩展后,x =0xffffffa5,取反后x = 0x0000005a,最终b=0x05。

下面在看一下关于符号位扩展的反编译代码

unsigned char a1 = 0xA5;

int a2 = a1;

这里扩展不需要补1,应为a1是unsigned类型的,所以编译器将上面代码译为

mov byte ptr [ebp-4], 0A5h

mov eax, dword ptr [ebp-4]

and eax, 0FFh ;eax = 0x000000a5

mov dword ptr [ebp-18h], eax

对于下面的c代码,需要进行符号位扩展

char a1 = 0xA5;

int a2 = a1;

反编译后,可以看到一条movsx带符号扩展指令

mov byte ptr [ebp-4], 0A5h

movsx eax,byte ptr [ebp-4] ;eax = 0xffffffa5

mov dword ptr [ebp-18h],eax

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值