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