私はこの小さなコード スニペットを持っています (これは私が抱えている問題の最小限の実例です):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void xorBuffer(unsigned char* dst, unsigned char* src, int len)
{
while (len != 0)
{
*dst ^= *src;
dst++;
src++;
len--;
}
}
int main()
{
unsigned char* a = malloc(32);
unsigned char* b = malloc(32);
int t;
memset(a, 0xAA, 32);
memset(b, 0xBB, 32);
xorBuffer(a, b, 32);
printf("result = ");
for (t = 0; t < 32; t++) printf("%.2x", a[t]);
printf("\n");
return 0;
}
このコードは、2 つの 32 バイト メモリ バッファの排他的論理和を実行することになっています (概念的には、これで実行する必要がありますa = a ^ b
)。0xAA ^ 0xBB = 0x11 なので、「11」を 32 回出力する必要があります。
私の問題は、これを MinGW-GCC (Windows) でコンパイルすると、デバッグ モード (最適化なし) で完全に動作しますが、-O3 から始まる最適化が有効になっている場合、xorBuffer ループの途中で SIGILL でクラッシュすることです。また、問題のあるループにprintfを入れると、再び完全に機能します。スタックの破損が疑われますが、ここで何が間違っているのかわかりません。
最適化を有効にしてGDBでデバッグしようとすると、すべてのGDBがすべての変数に対して「変数最適化」されていることが示されるため、原因が失われます(もちろん、変数を出力しようとすると、突然機能します)。
ここで一体何が起こっているのか誰か知っていますか?私はこの問題についてあまりにも長い時間を費やしてきました。先に進むには、適切に修正する必要があります。私の推測では、基本的な C ポインターの知識が欠けていると思いますが、コードは正しいように見えます。バッファのインクリメントによるものかもしれませんが、私の知る限りでは、sizeof(unsigned char) == 1
各バイトを 1 つずつ通過する必要があります。
価値があるのは、私の Linux ボックスで GCC を最適化してもコードが機能することです。
それで... ここでの取引は何ですか?ありがとう!
要求どおり、プログラム全体のアセンブリ出力:
-O2 あり:カチカチ
-O3 あり:クリック感
GCC 4.6.2(MinGWで実行)でこの動作を確認しました