私の C コード スニペットは、引数のアドレスを取得し、揮発性メモリの場所 (前処理されたコード) に格納します。
void foo(unsigned int x) {
*(volatile unsigned int*)(0x4000000 + 0xd4) = (unsigned int)(&x);
}
int main() {
foo(1);
while(1);
}
このコードのコンパイルには GCC の SVN バージョンを使用しました。関数の最後に、値がスタックに格納され、その値を指すアドレスが に格納されるfoo
ことを期待します。flag を使用して最適化なしでコンパイルすると、予想される ARM7TMDI アセンブリ出力が得られます (便宜上コメントされています)。1
0x40000d4
-O0
.align 2
.global foo
.type foo, %function
foo:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
sub sp, sp, #8
str r0, [sp, #4] @ 3. Store the argument on the stack
mov r3, #67108864
add r3, r3, #212
add r2, sp, #4 @ 4. Address of the stack variable
str r2, [r3, #0] @ 5. Store the address at 0x40000d4
add sp, sp, #8
bx lr
.size foo, .-foo
.align 2
.global main
.type main, %function
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
stmfd sp!, {r4, lr}
mov r0, #1 @ 1. Pass the argument in register 0
bl foo @ 2. Call function foo
.L4:
b .L4
.size main, .-main
.ident "GCC: (GNU) 4.4.0 20080820 (experimental)"
最初に引数をスタックに格納し、そこから に格納することは明らか0x40000d4
です。を使用して最適化してコンパイルすると-O1
、予期しない結果が得られます。
.align 2
.global foo
.type foo, %function
foo:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
sub sp, sp, #8
mov r2, #67108864
add r3, sp, #4 @ 3. Address of *something* on the stack
str r3, [r2, #212] @ 4. Store the address at 0x40000d4
add sp, sp, #8
bx lr
.size foo, .-foo
.align 2
.global main
.type main, %function
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
stmfd sp!, {r4, lr}
mov r0, #1 @ 1. Pass the argument in register 0
bl foo @ 2. Call function foo
.L4:
b .L4
.size main, .-main
.ident "GCC: (GNU) 4.4.0 20080820 (experimental)"
今回は、スタックの何かがまだ に格納されていても、引数がスタックに格納されることはありません0x40000d4
。
これは予想される/未定義の動作ですか? 何か間違ったことをしたのでしょうか、それとも実際に Compiler Bug™ を見つけたのでしょうか?