アセンブリメモ -ループ-
前回に続いてループ処理を見ていく.
#include <stdio.h> int main(){ int i; for (i=0; i<10; i++){ printf("%d\n", i); } return 0; }
0x080483fb <+0>: lea 0x4(%esp),%ecx 0x080483ff <+4>: and $0xfffffff0,%esp 0x08048402 <+7>: pushl -0x4(%ecx) 0x08048405 <+10>: push %ebp 0x08048406 <+11>: mov %esp,%ebp 0x08048408 <+13>: push %ecx 0x08048409 <+14>: sub $0x14,%esp 0x0804840c <+17>: movl $0x0,-0xc(%ebp) 0x08048413 <+24>: jmp 0x804842c <main+49> 0x08048415 <+26>: sub $0x8,%esp 0x08048418 <+29>: pushl -0xc(%ebp) 0x0804841b <+32>: push $0x80484d0 0x08048420 <+37>: call 0x80482d0 <printf@plt> 0x08048425 <+42>: add $0x10,%esp 0x08048428 <+45>: addl $0x1,-0xc(%ebp) 0x0804842c <+49>: cmpl $0x9,-0xc(%ebp) 0x08048430 <+53>: jle 0x8048415 <main+26> 0x08048432 <+55>: mov $0x0,%eax 0x08048437 <+60>: mov -0x4(%ebp),%ecx 0x0804843a <+63>: leave 0x0804843b <+64>: lea -0x4(%ecx),%esp 0x0804843e <+67>: ret
0x08048413にてjmp命令で0x804842cに飛ばされる.
0x804842cではcmp命令で0x9と変数iを比較され, jle命令で9より小さい場合, printfの処理へと移る.
ではbreakが入った場合どうなるか.
#include <stdio.h> int main(){ int i; for (i=0; i<10; i++){ if (i == 5){ break; } printf("%d\n", i); } return 0; }
0x080483fb <+0>: lea 0x4(%esp),%ecx 0x080483ff <+4>: and $0xfffffff0,%esp 0x08048402 <+7>: pushl -0x4(%ecx) 0x08048405 <+10>: push %ebp 0x08048406 <+11>: mov %esp,%ebp 0x08048408 <+13>: push %ecx 0x08048409 <+14>: sub $0x14,%esp 0x0804840c <+17>: movl $0x0,-0xc(%ebp) 0x08048413 <+24>: jmp 0x8048434 <main+57> 0x08048415 <+26>: cmpl $0x5,-0xc(%ebp) 0x08048419 <+30>: jne 0x804841d <main+34> 0x0804841b <+32>: jmp 0x804843a <main+63> 0x0804841d <+34>: sub $0x8,%esp 0x08048420 <+37>: pushl -0xc(%ebp) 0x08048423 <+40>: push $0x80484e0 0x08048428 <+45>: call 0x80482d0 <printf@plt> 0x0804842d <+50>: add $0x10,%esp 0x08048430 <+53>: addl $0x1,-0xc(%ebp) 0x08048434 <+57>: cmpl $0x9,-0xc(%ebp) 0x08048438 <+61>: jle 0x8048415 <main+26> 0x0804843a <+63>: mov $0x0,%eax 0x0804843f <+68>: mov -0x4(%ebp),%ecx 0x08048442 <+71>: leave 0x08048443 <+72>: lea -0x4(%ecx),%esp 0x08048446 <+75>: ret
breakのif文が0x08048415にあることが分かる.
条件式を満たさなければjne命令で0x804841dへと飛び, 満たしていればjmpで0x804843aへと飛ぶ.
ちなみにwhile文もfor文と同じようなアセンブラコードになる.
#include <stdio.h> int main(){ int i=0; while(i<=10){ printf("%d\n", i); i++; } return 0; }
0x080483fb <+0>: lea 0x4(%esp),%ecx 0x080483ff <+4>: and $0xfffffff0,%esp 0x08048402 <+7>: pushl -0x4(%ecx) 0x08048405 <+10>: push %ebp 0x08048406 <+11>: mov %esp,%ebp 0x08048408 <+13>: push %ecx 0x08048409 <+14>: sub $0x14,%esp 0x0804840c <+17>: movl $0x0,-0xc(%ebp) 0x08048413 <+24>: jmp 0x804842c <main+49> 0x08048415 <+26>: sub $0x8,%esp 0x08048418 <+29>: pushl -0xc(%ebp) 0x0804841b <+32>: push $0x80484d0 0x08048420 <+37>: call 0x80482d0 <printf@plt> 0x08048425 <+42>: add $0x10,%esp 0x08048428 <+45>: addl $0x1,-0xc(%ebp) 0x0804842c <+49>: cmpl $0xa,-0xc(%ebp) 0x08048430 <+53>: jle 0x8048415 <main+26> 0x08048432 <+55>: mov $0x0,%eax 0x08048437 <+60>: mov -0x4(%ebp),%ecx 0x0804843a <+63>: leave 0x0804843b <+64>: lea -0x4(%ecx),%esp 0x0804843e <+67>: ret