Chinaunix首页 | 论坛 | 博客
  • 博客访问: 67487
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 160
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-20 19:05
文章分类
文章存档

2016年(3)

2015年(15)

我的朋友

分类: C/C++

2015-05-25 22:13:20

寄存器
例①
返回值为int型的函数,一般存放在eax寄存器中

点击(此处)折叠或打开

  1. int test(){
  2.     int x=5;
  3.     return x;
  4. }

  5. int main()
  6. {
  7.     int y = 0;
  8.     y=test();
  9.     return y;
  10. }

点击(此处)折叠或打开

    1. (gdb) disassemble test
    2. Dump of assembler code for function test:
    3.    0x080483eb <+0>:    push %ebp
    4.    0x080483ec <+1>:    mov %esp,%ebp
    5.    0x080483ee <+3>:    sub $0x10,%esp
    6.    0x080483f1 <+6>:    movl $0x5,-0x4(%ebp) //赋值x
    7.    0x080483f8 <+13>:    mov -0x4(%ebp),%eax  //返回值x存入eax
    8.    0x080483fb <+16>:    leave 
    9.    0x080483fc <+17>:    ret 
    10. End of assembler dump.

  1. (gdb) disassemble main
  2. Dump of assembler code for function main:
  3.    0x080483fd <+0>:    push %ebp
  4.    0x080483fe <+1>:    mov %esp,%ebp
  5.    0x08048400 <+3>:    sub $0x10,%esp
  6.    0x08048403 <+6>:    movl $0x0,-0x4(%ebp)
  7.    0x0804840a <+13>:    call 0x80483eb <test>
  8.    0x0804840f <+18>:    mov %eax,-0x4(%ebp)  //从eax中取出返回值赋值给y变量
  9.    0x08048412 <+21>:    mov -0x4(%ebp),%eax   //使用y变量
  10.    0x08048415 <+24>:    leave
  11.    0x08048416 <+25>:    ret
  12. End of assembler dump.


栈内存
例②
C代码如下,结构体strTEST 不止4个字节,eax寄存器是放不下的,那么来看下编译器回如何传递test函数的返回值

点击(此处)折叠或打开

  1. typedef struct {
  2.     int i;
  3.     char a;
  4. }strTEST;

  5. strTEST test(){
  6.     strTEST x={5,'a'};
  7.     return x;
  8. }

  9. strTEST main()
  10. {
  11.     strTEST y = {0,0};
  12.     y=test();
  13.     return y;
  14. }


点击(此处)折叠或打开

    1. (gdb) disassemble test
    2. Dump of assembler code for function test:
    3.    0x0804843b <+0>:    push %ebp
    4.    0x0804843c <+1>:    mov %esp,%ebp
    5.    0x0804843e <+3>:    sub $0x10,%esp
    6.    0x08048441 <+6>:    movl $0x5,-0x8(%ebp)  //给x.i赋值5 
    7.    0x08048448 <+13>:    movb $0x61,-0x4(%ebp) //给x.a赋值‘a’
    8.    0x0804844c <+17>:    mov 0x8(%ebp),%ecx  //上一层栈的y结构体变量的地址赋给ecx
    9.    0x0804844f <+20>:    mov -0x8(%ebp),%eax  // x.i值存到eax
    10.    0x08048452 <+23>:    mov -0x4(%ebp),%edx  // x.a值存到edx
    11.    0x08048455 <+26>:    mov %eax,(%ecx)  //eax,也就是x.i的值 存到y.i位置,  
    12.    0x08048457 <+28>:    mov %edx,0x4(%ecx)//edx,也就是x.a的值 存到y.a的位置 <==== 至此可以看到,test函数还没有返回,x结构体的值已经传递到上一层栈中y变量的地址空间了
    13.    0x0804845a <+31>:    mov 0x8(%ebp),%eax //y变量的地址存到eax
    14.    0x0804845d <+34>:    leave 
    15.    0x0804845e <+35>:    ret $0x4
    16. End of assembler dump.

  1. (gdb) disassemble main
  2. Dump of assembler code for function main:
  3.    0x08048461 <+0>:    lea 0x4(%esp),%ecx
  4.    0x08048465 <+4>:    and $0xfffffff0,%esp
  5.    0x08048468 <+7>:    pushl -0x4(%ecx)
  6.    0x0804846b <+10>:    push %ebp
  7.    0x0804846c <+11>:    mov %esp,%ebp
  8.    0x0804846e <+13>:    push %ecx
  9.    0x0804846f <+14>:    sub $0x24,%esp
  10.    0x08048472 <+17>:    mov %ecx,%eax
  11.    0x08048474 <+19>:    mov (%eax),%eax
  12.    0x08048476 <+21>:    mov %eax,-0x1c(%ebp)
  13.    0x08048479 <+24>:    mov %gs:0x14,%eax
  14.    0x0804847f <+30>:    mov %eax,-0xc(%ebp)
  15.    0x08048482 <+33>:    xor %eax,%eax
  16.    0x08048484 <+35>:    movl $0x0,-0x14(%ebp)
  17.    0x0804848b <+42>:    movb $0x0,-0x10(%ebp)
  18.    0x0804848f <+46>:    lea -0x14(%ebp),%eax
  19.    0x08048492 <+49>:    push %eax
  20.    0x08048493 <+50>:    call 0x804843b <test>
  21.    0x08048498 <+55>:    mov -0x1c(%ebp),%ecx
  22.    0x0804849b <+58>:    mov -0x14(%ebp),%eax  //此处-0x14(%ebp)就是y.i的值,在test函数中已完成赋值,可以直接拿来用了。
  23.    0x0804849e <+61>:    mov -0x10(%ebp),%edx  //同上,y.a的值
  24.    0x080484a1 <+64>:    mov %eax,(%ecx)
  25.    0x080484a3 <+66>:    mov %edx,0x4(%ecx)
  26.    0x080484a6 <+69>:    mov -0x1c(%ebp),%eax
  27.    0x080484a9 <+72>:    mov -0xc(%ebp),%edx
  28.    0x080484ac <+75>:    xor %gs:0x14,%edx
  29.    0x080484b3 <+82>:    je 0x80484ba <main+89>
  30.    0x080484b5 <+84>:    call 0x8048310 <__stack_chk_fail@plt>
  31.    0x080484ba <+89>:    mov -0x4(%ebp),%ecx
  32.    0x080484bd <+92>:    leave
  33.    0x080484be <+93>:    lea -0x4(%ecx),%esp
  34.    0x080484c1 <+96>:    ret $0x4
  35. End of assembler dump.


阅读(2212) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~