汇编技术内幕(3) 作者: 时间:2016-11-24 来源:网络 加入技术交流群 扫码加入和技术大咖面对面交流海量资料库查询 收藏 局部变量的栈分配 下面我们分析一下C编译器如何处理局部变量的分配,为此先给出如下程序: #vi test2.c int main() { int i; int j=2; i=3; i=++i; return i+j; } 编译该程序,产生二进制文件,并利用mdb来观察程序运行中的stack的状态: #gcc test2.c -o test2 #mdb test2 Loading modules: [ libc.so.1 ] > main::dis main: pushl %ebp main+1: movl %esp,%ebp ; main至main+1,创建Stack Frame main+3: subl $8,%esp ; 为局部变量i,j分配栈空间,并保证栈16字节对齐 main+6: andl $0xf0,%esp main+9: movl $0,%eax main+0xe: subl %eax,%esp ; main+6至main+0xe,再次保证栈16字节对齐 main+0x10: movl $2,-8(%ebp) ; 初始化局部变量j的值为2 main+0x17: movl $3,-4(%ebp) ; 给局部变量i赋值为3 main+0x1e: leal -4(%ebp),%eax ; 将局部变量i的地址装入到EAX寄存器中 main+0x21: incl (%eax) ; i++ main+0x23: movl -8(%ebp),%eax ; 将j的值装入EAX main+0x26: addl -4(%ebp),%eax ; i+j并将结果存入EAX,作为返回值 main+0x29: leave ; 撤销Stack Frame main+0x2a: ret ; main函数返回 > 通过mdb对程序运行时的寄存器和栈的观察和分析,可以得出局部变量在栈中的访问和分配及释放方式: 1.局部变量的分配,可以通过esp减去所需字节数 subl $8,%esp 2.局部变量的释放,可以通过leave指令 leave 3.局部变量的访问,可以通过ebp减去偏移量 movl -8(%ebp),%eax addl -4(%ebp),%eax 问题:当存在2个以上的局部变量时,如何进行栈对齐? 在上篇文章中,提到subl $8,%esp语句除了分配栈空间外,还有一个作用就是栈对齐。那么本例中,由于i和j正好是8字节,那么如果存在2个以上的局部变量时,如何同时满足空间分配和栈对齐呢?
评论