昨天用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;
只要涉及到右移,保證操作數是無符號就可以了。