- 论坛徽章:
- 0
|
关于第一个问题,现在有点新的认识
- [neil@localhost tmp]$ cat main.c
- void foo(void)
- {
- int a,b,c,d;
- b=2;
- a=1;
- c=3;
- d=4;
- }
- int main()
- {
- foo();
- return 0;
- }
- [neil@localhost tmp]$ gcc -S main.c
- [neil@localhost tmp]$ cat main.s
- .file "main.c"
- .text
- .globl foo
- .type foo, @function
- foo:
- pushl %ebp
- movl %esp, %ebp
- subl $16, %esp
- movl $2, -12(%ebp)
- movl $1, -16(%ebp)
- movl $3, -8(%ebp)
- movl $4, -4(%ebp)
- leave
- ret
- .size foo, .-foo
- .globl main
- .type main, @function
- main:
- leal 4(%esp), %ecx
- andl $-16, %esp
- pushl -4(%ecx)
- pushl %ebp
- movl %esp, %ebp
- pushl %ecx
- call foo
- movl $0, %eax
- popl %ecx
- popl %ebp
- leal -4(%ecx), %esp
- ret
- .size main, .-main
- .ident "GCC: (GNU) 4.1.2 20070502 (Red Hat 4.1.2-12)"
- .section .note.GNU-stack,"",@progbits
- [neil@localhost tmp]$
复制代码
从这里可以看出这么几点:
1、我原来的错误在于,认为哪个变量被赋值,则该变量入栈,现在看来,只要变量被声明,它在栈中的位置也就确定了,这可以从上面的汇编看出来。
3、变量的顺序问题,变量声明的顺序为a,b,c,d,但在栈中存储的顺序(由高地址到低地址)为d,c,b,a,我们能不能这样理解,当把esp减去某个值从而在栈中划分出一块空间后,虽然这块空间实际是在栈上,但分配变量时却把他当作堆(数据段?)来对待,从而按变量声明的顺序从低地址开始分配。(纯属猜测,因为若按push那种入栈方式的话,这四个变量在其中的存储方式不应该是这样)
2、变量的访问,访问栈中的变量是通过类似于-4(%ebp),-8(%ebp)这样的基址+偏移(不知道这个说法是否准确,瞎说的)进行的,而不是通过pop,也就是说,即使变量是采用push这种入栈方式的话
,我们也可以利用ebp来很方便的访问所有变量。
______________________________________________
当然,以上所有东西可能都是平台、编译器或者os相关的。这也是我发这帖子的原因,因为实在搞不清哪些问题是平台决定的,哪些问题是编译器决定的,还有哪些问题是os决定的。 |
|