学习笔记1

第一课  汇编代码的工作过程

         源文件main.c代码如下:

int g(int x)  
{  
  return x + 7;  
}  
  
int f(int x)  
{  
  return g(x);  
}  
  
int main(void)  
{  
  return f(5) + 3;  
}



        执行gcc -S main.c -m32后,生成main.s,即汇编指令。去除以"."开头的行,机器指令的指令如下:

<span style="font-size:18px;"> 
  1         .file   "main.c"
  2         .text
  3 .globl g
  4         .type   g, @function
  5 g:
  6         pushl   %ebp
  7         movl    %esp, %ebp
  8         movl    8(%ebp), %eax
  1         .file   "main.c"
  2         .text
  3 .globl g
  4         .type   g, @function
  5 g:
  6         pushl   %ebp
  7         movl    %esp, %ebp
  8         movl    8(%ebp), %eax
  9         addl    $7, %eax
 10         popl    %ebp
 11         ret
 12         .size   g, .-g
 13 .globl f
 14         .type   f, @function
 15 f:
 16         pushl   %ebp
 17         movl    %esp, %ebp
 18         subl    $4, %esp
 19         movl    8(%ebp), %eax
 20         movl    %eax, (%esp)
 21         call    g
 22         leave
 23         ret
 24         .size   f, .-f
 25 .globl main
 26         .type   main, @function
 27 main:
 28         pushl   %ebp
 29         movl    %esp, %ebp
 30         subl    $4, %esp
 31         movl    $5, (%esp)
 32         call    f
 33         addl    $3, %eax
 34         leave
 35         ret
 36         .size   main, .-main
 37         .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4)"
 38         .section        .note.GNU-stack,"",@progbits</span>



    从main函数开始,下图为不同时期中不同地址存储的数据:

        

0、开始时,ebpesp均指向地址1

1、执行pushl  %ebp,即

   subl $4, %esp

   movl (%ebp), $esp

   esp指向地址2,地址2中存放ebp的地址1

2movl   %esp, %ebp

   ebp指向esp的地址,即指向地址2.

3subl   $4, %esp

   esp移,指向地址3

4movl   $5, (%esp)

   esp指向的地址(地址3)中存储值5

5call   f

   执行指令pushl %eip(*)movlf, %eip(*),即esp首先指向地址4,地址4中存入当前eip指向的地址(call的下一行,即代码33行);eip指向代码段f

6pushl  %ebp

     esp下移,指向地址5,地址5中存放ebp指向的地址(地址3

7movl   %esp, %ebp

     ebp指向esp指向的地址(地址5

8subl   $4, %esp

      esp下移,指向地址6

9movl   8(%ebp), %eax

    eax=ebp上移两个地址单位的地址中的值5

10movl   %eax, (%esp)

   esp指向的地址(地址6)中存入eax=5

11call   g

   esp指向下一个地址(地址7),地址7中存入eip指向的地址(代码22行),eip指向代码段g

12pushl  %ebp

   esp指向下一个地址(地址8),地址8中存入ebp的地址(地址5

13movl   %esp, %ebp

   ebp指向esp指向的地址(地址8

14movl   8(%ebp), %eax

   eax=ebp指向的上两个地址(地址6)中的值=5

15addl   $7, %eax

   eax=5+7=12

16popl   %ebp

   popl指令执行的是

   movl (%esp),%ebp

   addl $4,$esp

   ebp指向esp地址中的值(地址5),esp指向上一个地址(地址7

17ret

    ret指令执行的是

   popl %eip

   eip指向esp地址中的值(代码22行,函数f),esp指向上一个地址(地址6

18leave

    leave指令执行的是

   movl %ebp, %esp

   popl %ebp

   esp指向ebp指向的地址(地址5),ebp指向esp地址中存放的值(地址2),esp指向上一个地址(地址4

19ret

    ret指令执行的是

    popl %eip

   eip指向当前esp指向的地址(地址4)中的值(代码33行),esp指向上一个地址(地址3

20addl   $3, %eax

   eax=3+12=15

21leave

    leave指令执行的是

    movl %ebp, %esp

    popl %ebp

   esp指向ebp指向的地址(地址2),ebp指向esp指向的地址(地址2)中的值(地址1),esp指向上一个地址(地址1

22ret

   eip指向esp地址(地址1)中的值,esp指向上一个地址。

至此退出整个main函数。


课堂笔记:

1、pushl $0x11指令执行的是

     subl $4, %esp

     movl $0x11, (%esp)

    esp指向下一个地址,地址中存入push的值

2、popl %eax 指令执行的是:

    movl(%esp), %eax

    addl $4, %esp

    eax中存入esp中的值,esp指向上一个地址

3、call 0x12345 指令执行的是

    pushl %eip

    movl 0x12345, %eip

    esp指向下一个地址,地址中存入当前eip的地址,eip 指向跳转的指令

4、ret 执行的是popl %eip,eip指向当前esp中存放的值,esp指向上一个地址

5、leave 执行的是

    movl %ebp, %esp

    popl %ebp

    esp指向ebp指向的地址,ebp指向esp指向地址中的值,esp指向上一个地址。即esp指向ebp的上一个地址,ebp指向自身存储的值(为一地址)。

6、寄存器eax中存储函数返回值。


赵豫峰 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-10000290


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值