昨天用C/C++写Base64编码,结果老是不对,
比如
unsigned char A =;
unsigned char B = ;
unsigned char C = ;
unsigned char a, b, c, d;
a = A >> 2;
b=(A << 6) >> 2|(B>>4);
c = ((B << 4)) >> 2) | (C >> 6);
d = (C << 2) >> 2;
结果发现bcd值都不对
但是写成
b = A<< 6;
b = b >> 2;
b=b|B>>4;
就可以,查看b计算两种方式汇编
第一种
00BACB66 movzx eax,byte ptr [ebp-1F9h]
00BACB6D shl eax,6
00BACB70 sar eax,2
00BACB73 mov byte ptr [ebp-1C9h],al
第二种
00BACB79 movzx eax,byte ptr [ebp-1F9h]
00BACB80 shl eax,6
00BACB83 mov byte ptr [ebp-1EDh],al
00BACB89 movzx eax,byte ptr [ebp-1EDh]
00BACB90 sar eax,2
00BACB93 mov byte ptr [ebp-1EDh],al
问题就在指令sar,这是算数右移位指令,会保留最高位,而第二种可以是因为movzx 将高位已经置零
找到了原因,可以写为
a = A >> 2;
b=((unsigned char)(A << 6)) >> 2|(B>>4);
c = (((unsigned char)(B << 4)) >> 2) | (C >> 6);
d = ((unsigned char)(C << 2)) >> 2;
只要涉及到右移,保证操作数是无符号就可以了。