#include <stdio.h>
void swap(int *a,int *b)
{
*a=*a^*b;
*b=*a^*b;
*a=*a^*b;
}
int main(int argc,char **argv)
{
int a=100;
int b=1000;
swap(&a,&b);
printf("the num of sub is %d/n",a-b);
return(a-b);
}
C语言函数的堆栈细述
1堆栈的增加方向是向着低地址方向的
2函数的返回地址是在调用函数里开辟的
3可以这样来表示调用函数时栈桢的变化的esp(栈的顶部的指针)-->ebp(栈的底部)(本操作发生在被调用函数中)
4地址变量也会给开辟空间
5返回值放入寄存器中
5
.file "asm.c"
.version "01.01"
gcc2_compiled.:
.text
.align 4
.globl swap
.type swap,@function
swap:
pushl %ebp //保存栈桢的底部
movl %esp, %ebp //更新栈桢的底部,移动到新的栈桢
movl 8(%ebp), %ecx //取出&a---->ecx,edx//这两个寄存器在调用函数中就被保存起来 //了,不需要被调用函数的维护
movl 8(%ebp), %edx
movl 12(%ebp), %eax //取出&b---->eax,,并取出b
movl (%eax), %eax
xorl (%edx), %eax //异或a,b,结果放到eax
movl %eax, (%ecx) //保存到a //下面有编译器生成的多余的指令
movl 12(%ebp), %ecx //取出&b---->ecx
movl 8(%ebp), %edx //取出&a---->edx
movl 12(%ebp), %eax //取出&b---->eax 并取出b
movl (%eax), %eax
xorl (%edx), %eax //异或a,b,结果放到eax
movl %eax, (%ecx)
movl 8(%ebp), %ecx
movl 8(%ebp), %edx
movl 12(%ebp), %eax
movl (%eax), %eax
xorl (%edx), %eax
movl %eax, (%ecx)
popl %ebp
ret
.Lfe1:
.size swap,.Lfe1-swap
.section .rodata
.LC0:
.string "the num of sub is %d/n"
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp //因为main本身就是一个函数、所以,跟swap时一样处理的
movl %esp, %ebp
subl $8, %esp //为整形a,b分配空间
movl $100, -4(%ebp)
movl $1000, -8(%ebp)
subl $8, %esp //为地址分配空间
leal -8(%ebp), %eax
pushl %eax //作为参数调用压栈
leal -4(%ebp), %eax
pushl %eax
call swap
addl $16, %esp
subl $8, %esp
movl -8(%ebp), %edx
movl -4(%ebp), %eax
subl %edx, %eax
pushl %eax
pushl $.LC0
call printf
addl $16, %esp
movl -8(%ebp), %edx
movl -4(%ebp), %eax
subl %edx, %eax
movl %eax, %eax
leave //movl %ebp,%esp popl %ebp
ret
.Lfe2:
.size main,.Lfe2-main
.ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)"
.Lfe1:
.size swap,.Lfe1-swap
.section .rodata
.LC0:
.string "the num of sub is %d/n"
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $100, -4(%ebp)
movl $1000, -8(%ebp)
subl $8, %esp
leal -8(%ebp), %eax
pushl %eax
leal -4(%ebp), %eax
pushl %eax
call swap
addl $16, %esp
subl $8, %esp
movl -8(%ebp), %edx
movl -4(%ebp), %eax
subl %edx, %eax
pushl %eax
pushl $.LC0
call printf
addl $16, %esp
movl -8(%ebp), %edx
movl -4(%ebp), %eax
subl %edx, %eax
movl %eax, %eax
leave
ret
.Lfe2:
.size main,.Lfe2-main
.ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)"