寄存器
例①
返回值为int型的函数,一般存放在eax寄存器中
-
int test(){
-
int x=5;
-
return x;
-
}
-
-
int main()
-
{
-
int y = 0;
-
y=test();
-
return y;
-
}
-
-
(gdb) disassemble test
-
Dump of assembler code for function test:
-
0x080483eb <+0>: push %ebp
-
0x080483ec <+1>: mov %esp,%ebp
-
0x080483ee <+3>: sub $0x10,%esp
-
0x080483f1 <+6>: movl $0x5,-0x4(%ebp) //赋值x
-
0x080483f8 <+13>: mov -0x4(%ebp),%eax //返回值x存入eax
-
0x080483fb <+16>: leave
-
0x080483fc <+17>: ret
-
End of assembler dump.
-
(gdb) disassemble main
-
Dump of assembler code for function main:
-
0x080483fd <+0>: push %ebp
-
0x080483fe <+1>: mov %esp,%ebp
-
0x08048400 <+3>: sub $0x10,%esp
-
0x08048403 <+6>: movl $0x0,-0x4(%ebp)
-
0x0804840a <+13>: call 0x80483eb <test>
-
0x0804840f <+18>: mov %eax,-0x4(%ebp) //从eax中取出返回值赋值给y变量
-
0x08048412 <+21>: mov -0x4(%ebp),%eax //使用y变量
-
0x08048415 <+24>: leave
-
0x08048416 <+25>: ret
-
End of assembler dump.
-
栈内存
例②
C代码如下,结构体strTEST 不止4个字节,eax寄存器是放不下的,那么来看下编译器回如何传递test函数的返回值
-
typedef struct {
-
int i;
-
char a;
-
}strTEST;
-
-
strTEST test(){
-
strTEST x={5,'a'};
-
return x;
-
}
-
-
strTEST main()
-
{
-
strTEST y = {0,0};
-
y=test();
-
return y;
-
}
-
-
(gdb) disassemble test
-
Dump of assembler code for function test:
-
0x0804843b <+0>: push %ebp
-
0x0804843c <+1>: mov %esp,%ebp
-
0x0804843e <+3>: sub $0x10,%esp
-
0x08048441 <+6>: movl $0x5,-0x8(%ebp) //给x.i赋值5
-
0x08048448 <+13>: movb $0x61,-0x4(%ebp) //给x.a赋值‘a’
-
0x0804844c <+17>: mov 0x8(%ebp),%ecx //上一层栈的y结构体变量的地址赋给ecx
-
0x0804844f <+20>: mov -0x8(%ebp),%eax // x.i值存到eax
-
0x08048452 <+23>: mov -0x4(%ebp),%edx // x.a值存到edx
-
0x08048455 <+26>: mov %eax,(%ecx) //eax,也就是x.i的值 存到y.i位置,
-
0x08048457 <+28>: mov %edx,0x4(%ecx)//edx,也就是x.a的值 存到y.a的位置 <==== 至此可以看到,test函数还没有返回,x结构体的值已经传递到上一层栈中y变量的地址空间了
-
0x0804845a <+31>: mov 0x8(%ebp),%eax //y变量的地址存到eax
-
0x0804845d <+34>: leave
-
0x0804845e <+35>: ret $0x4
-
End of assembler dump.
-
(gdb) disassemble main
-
Dump of assembler code for function main:
-
0x08048461 <+0>: lea 0x4(%esp),%ecx
-
0x08048465 <+4>: and $0xfffffff0,%esp
-
0x08048468 <+7>: pushl -0x4(%ecx)
-
0x0804846b <+10>: push %ebp
-
0x0804846c <+11>: mov %esp,%ebp
-
0x0804846e <+13>: push %ecx
-
0x0804846f <+14>: sub $0x24,%esp
-
0x08048472 <+17>: mov %ecx,%eax
-
0x08048474 <+19>: mov (%eax),%eax
-
0x08048476 <+21>: mov %eax,-0x1c(%ebp)
-
0x08048479 <+24>: mov %gs:0x14,%eax
-
0x0804847f <+30>: mov %eax,-0xc(%ebp)
-
0x08048482 <+33>: xor %eax,%eax
-
0x08048484 <+35>: movl $0x0,-0x14(%ebp)
-
0x0804848b <+42>: movb $0x0,-0x10(%ebp)
-
0x0804848f <+46>: lea -0x14(%ebp),%eax
-
0x08048492 <+49>: push %eax
-
0x08048493 <+50>: call 0x804843b <test>
-
0x08048498 <+55>: mov -0x1c(%ebp),%ecx
-
0x0804849b <+58>: mov -0x14(%ebp),%eax //此处-0x14(%ebp)就是y.i的值,在test函数中已完成赋值,可以直接拿来用了。
-
0x0804849e <+61>: mov -0x10(%ebp),%edx //同上,y.a的值
-
0x080484a1 <+64>: mov %eax,(%ecx)
-
0x080484a3 <+66>: mov %edx,0x4(%ecx)
-
0x080484a6 <+69>: mov -0x1c(%ebp),%eax
-
0x080484a9 <+72>: mov -0xc(%ebp),%edx
-
0x080484ac <+75>: xor %gs:0x14,%edx
-
0x080484b3 <+82>: je 0x80484ba <main+89>
-
0x080484b5 <+84>: call 0x8048310 <__stack_chk_fail@plt>
-
0x080484ba <+89>: mov -0x4(%ebp),%ecx
-
0x080484bd <+92>: leave
-
0x080484be <+93>: lea -0x4(%ecx),%esp
-
0x080484c1 <+96>: ret $0x4
-
End of assembler dump.
-
阅读(2302) | 评论(0) | 转发(0) |