循环语句的汇编表示

1.for循环

循环语句的代码是:

int  sum(int x)

{

int i;

int res=0;

for(i=0;i<=x;i++)

res+=i;

return res;

}

产生的汇编代码为:

00000000<sum>:

0: 55 push %ebp

1: 89 e5        mov %esp,%ebp

3: 83 ec 10 sub $0x10,%esp

6: c7 45 fc 00 00 00 00   movl $0x0,-0x4(%ebp)

d: c7 45 f8 00 00 00 00    movl $0x0,-0x8(%ebp)

14: eb 0a   jmp 20 <sum+0x20>

16: 8b 45 f8    mov -0x8(%ebp),%eax

19: 01 45 fc    add %eax,-0x4(%ebp)

1c: 83 45 f8 01   addl $0x1,-0x8(%ebp)

20: 8b 45 f8    mov -0x8(%ebp),%eax

23: 3b 45 08    cmp 0x8(%ebp),%eax

26: 7e ee    jle 16 <sum+0x16>

28: 8b 45 fc    mov -0x4(%ebp),%eax

2b: c9     leave

2c: c3        ret

编译器为函数分配了16字节的堆栈,变量存放在ebp偏移4字节处,而变量res存放在ebp偏移8字节处。上面的C代码可以写成以下伪代码:

int sum(int x)

{

int i=0;

int res=0;

jmp comp;


loop:

res+=x;

i++;


comp:

if(i<=x)

jmp loop;


}

这样,这段伪代码与上面的汇编代码就可以对应起来。

2.while循环

代码如下:

int  sum(int x)

2{

int i;

int res=0;

while(i<=x)

{

res+=i;

i++;

}

return  res;

}

产生的汇编代码如下:

00000000<sum>:

0: 55     push %ebp

1: 89  e5   mov %esp,%ebp

3: 83  ec  10    sub $0x10,%esp

6: c7  45   fc 00 00 00 00 movl $0x0,-0x4(%ebp)

d: eb  0a    jmp 19 <sum+0x19>

f: 8b  45 f8   mov -0x8(%ebp),%eax

12: 01  45 fc   add %eax,-0x4(%ebp)

15: 83  45 f8 01   addl $0x1,-0x8(%ebp)

19: 8b  45 f8    mov -0x8(%ebp),%eax

1c: 3b  45 08   cmp 0x8(%ebp),%eax

1f: 7e ee  jle   f <sum+0xf>

21: 8b 45  fc   mov -0x4(%ebp),%eax

24: c9   leave

25: c3    ret

从上面的汇编代码看出,变量i存放在寄存器ebp偏移8字节处,res存放在寄存器ebp偏移4字节处,返回值在寄存器eax中。

上面的C代码可以写成如下伪代码的形式:

int sum(int x)

{

int i=0;

int res=0;

jmp  comp;


loop

res+=i;

i++;


comp:

if(i<=x)

goto  loop;

}

3.do...while循环

C程序如下:

int  sum(int x)

{

int  i=0;

int  res=0;

do{

res+=i;

i++;

}while(i<=x);

return  res;

}

产生的汇编代码如下:

00000000<sum>:

0: 55     push %ebp

1: 89 e5    mov %esp,%ebp

3: 83 ec 10   sub $0x10,%esp

6: c7 45 f8 00 00 00 00  movl $0x0,-0x8(%ebp)

d: c745  fc 00 00 00 00    movl $0x0,-0x4(%ebp)

14: 8b 45 f8   mov -0x8(%ebp),%eax

17: 01 45 fc   add %eax,-0x4(%ebp)

1a: 83 45 f8 01   addl $0x1,-0x8(%ebp)

1e: 8b 45 f8    mov -0x8(%ebp),%eax

21: 3b 45 08    cmp 0x8(%ebp),%eax

24: 7e ee    jle 14 <sum+0x14>

26: 8b 45 fc   mov -0x4(%ebp),%eax

29: c9   leave

2a: c3    ret

变量i存放在寄存器ebp偏移8字节处,变量res存放在寄存器偏移4字节处。

do...while循环产生的汇编代码与while循环稍有不同,因为do...while循环至少执行一次。

上面的C代码转为伪代码为:

int  sum(int x)

{

int i=0;

int res=0;

loop:

res+=i;

i++;

if(i<=x)

goto  loop;

}

编译器产生的汇编代码在不同的环境,gcc版本和优化级别情形下,可能有所不同,以上的汇编代码是在ubuntu中,使用gcc 4.7.2,在默认优化级别下产生的。


你可能感兴趣的:(linux,汇编,gcc,循环语句)