いくつかの逆コンパイルされたCコードを見ると、私はこれを見ました:
movl -0xc(%rbp), %esi
movl %esi, -0x8(%rbp)
これは次のCコードに対応します。
x = y;
これは私に考えました:gccがy
を%esi
に移動し、x
をy
に直接移動するのではなく、%esi
をx
に移動する方法
重要な場合、これはC全体と逆コンパイルされたコードです。
int main(void) {
int x, y, z;
while(1) {
x = 0;
y = 1;
do {
printf("%d\n", x);
z = x + y;
x = y;
y = z;
} while(x < 255);
}
}
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movl $0x0, -0x4(%rbp)
movl $0x0, -0x8(%rbp) ; x = 0
movl $0x1, -0xc(%rbp) ; y = 1
; printf
leaq 0x56(%rip), %rdi
movl -0x8(%rbp), %esi
movb $0x0, %al
callq 0x100000f78
; z = x + y
movl -0x8(%rbp), %esi ; x -> esi
addl -0xc(%rbp), %esi ; y + esi
movl %esi, -0x10(%rbp) ; z = esi
; x = y
movl -0xc(%rbp), %esi
movl %esi, -0x8(%rbp)
; y = z
movl -0x10(%rbp), %esi
movl %esi, -0xc(%rbp)
movl %eax, -0x14(%rbp) ; not sure... I believe printf return value?
cmpl $0xff, -0x8(%rbp) ; x < 255
jl 0x100000f3d ; do...while(x < 255)
jmp 0x100000f2f ; while(1)
ほとんどのx86命令(movsb
などの特殊な命令を除く)は、1つのメモリ位置にしかアクセスできません。したがって、メモリからメモリへの移動には、2つのmov
命令でレジスタを通過する必要があります。
mov
命令は、次の方法で使用できます。
mov mem, reg
mov reg, mem
mov reg, reg
mov reg, imm
mov mem, imm
mov mem, mem
はありません。
最適化を使用してコンパイルした場合、変数はレジスタに配置されるため、これは問題になりません。