Iba*_*ijo 8 c++ c++builder c++builder-2009
我正在迁移旧C++代码的一些部分,最初使用CodeGear C++Builder®2009版本12.0.3170.16989编译
以下代码 - 更大版本的最小版本 - -34使用任何现代编译器输出.虽然,在原始平台中输出84:
char Key[4];
Key[0] = 0x1F;
Key[1] = 0x01;
Key[2] = 0x8B;
Key[3] = 0x55;
for(int i = 0; i < 2; i++) {
Key[i] = Key[2*i] ^ Key[2*i + 1];
}
std::cout << (int) Key[1] << std::endl;
Run Code Online (Sandbox Code Playgroud)
for(int i = 0; i < 2; i++) {
char a = Key[2*i];
char b = Key[2*i + 1];
char c = a ^ b;
Key[i] = c;
}
Run Code Online (Sandbox Code Playgroud)
此外,手动展开循环似乎适用于两个编译器:
Key[0] = Key[0] ^ Key[1];
Key[1] = Key[2] ^ Key[3];
Run Code Online (Sandbox Code Playgroud)
我必须匹配旧代码的行为.谁能帮助我理解为什么原始编译器产生这些结果?
这似乎是一个错误:
这条线
Key[i] = Key[2*i] ^ Key[2*i + 1];
Run Code Online (Sandbox Code Playgroud)
生成以下代码:
00401184 8B55F8 mov edx,[ebp-$08]
00401187 8A4C55FD mov cl,[ebp+edx*2-$03]
0040118B 8B5DF8 mov ebx,[ebp-$08]
0040118E 304C1DFC xor [ebp+ebx-$04],cl
Run Code Online (Sandbox Code Playgroud)
那没有意义.这类似于:
Key[i] ^= Key[i*2 + 1];
Run Code Online (Sandbox Code Playgroud)
这解释了结果如何:0x01 ^ 0x55确实0x54,或者84.
它应该是这样的:
mov edx,[ebp-$08]
mov cl,[ebp+edx*2-$04]
xor cl,[ebp+edx*2-$03]
mov [ebp+ebx-$04],cl
Run Code Online (Sandbox Code Playgroud)
所以这绝对是一个代码生成错误.它似乎一直持续到现在,C++ Builder 10.2 Tokyo,用于"经典"(Borland)编译器.
但是,如果我使用"new"(clang)编译器,它会产生222.生成的代码是:
File7.cpp.12: Key[i] = Key[2*i] ^ Key[2*i + 1];
004013F5 8B45EC mov eax,[ebp-$14]
004013F8 C1E001 shl eax,$01
004013FB 0FB64405F0 movzx eax,[ebp+eax-$10]
00401400 8B4DEC mov ecx,[ebp-$14]
00401403 C1E101 shl ecx,$01
00401406 0FB64C0DF1 movzx ecx,[ebp+ecx-$0f]
0040140B 31C8 xor eax,ecx
0040140D 88C2 mov dl,al
0040140F 8B45EC mov eax,[ebp-$14]
00401412 885405F0 mov [ebp+eax-$10],dl
Run Code Online (Sandbox Code Playgroud)
这对我来说并不是最佳的(我使用O2和O3的结果相同),但它会产生正确的结果.
| 归档时间: |
|
| 查看次数: |
308 次 |
| 最近记录: |