学习笔记 变长栈帧

来源:互联网 发布:苏州买茶叶知乎 编辑:程序博客网 时间:2024/05/22 07:46
/*支持变长栈帧
一般的代码在编译的时候编译器事先就能知道需要为栈帧分配多大的空间,但有的时候我们需要用到动态分配,即在运行的时候才知道需要多大的空间*/
#include<iostream>
using namespace std;
long vframe(long n, long idx, long *q)
{
 long i;
 long *p[n];
 p[0] = &i;
 for (i = 1; i < n; i++)
  p[i] = q;
 return *p[idx];
}
/*这个函数接受3个参数,n idx *q
创建一个局部变量i
创建一个指针数组p,有n个元素
p[0]设为i的地址
p[1]到p[n-1]的值设为q
返回p[idx]的值

vframe:
1         pushq    %rdp          
2         moveq    %rsp,%rdp         设置基指针
3         subq     $16, %rsp         分配16字节的空间来储存i,i为long,只需要8个字节,但这里分配了16个字节,是为了内存16位对齐的原因,多余的8个字节将不被使用
4         leaq     22(,%rdi,8),%rax   %rax=8n+22
5         andq     $-16,%rax          %rax=(8n+22)&-16  这个计算将求得向下舍入16的最小的倍数,当n为奇数的时候为8n+8;当n为偶数的时候为8n+16;
6         subq     %rax,%rsp          分配空间
7         leaq     7(%rsp),%rax
8         shrq     $3,%rax
9         leaq     0(,%rax,8),%r8     以上计算将求得离得最近的8数 即&p[0],并出入%r8中
10        movq     %r8,%rcx           %rcx=p
11        .L3:
           movq       %rdx,(%rcx,%rax,8)       将p[i]的值设为q
           addq       $1,%rax                  i++
           movq       %rax,-8(%rdp)            i值存进栈中
             .L4:
            movq       -8(%rdp),%rax            获取i值
            cmpq        %rdi,%rax               对比i值和n值
                 jl          .L3                     如果小于则跳转L3
*/

4的计算过程:
                            8n+22=n*2^3+22
                            -16的二进制=16的补码非+1
                             16=0000 0000 0000.....0001 0000
                             ^16=1111111111111.......1110 1111  +1=1111111111........1111 0000
                         
                             (n)  0  0   0
                           +1  0 1  1   0
与 1111......... 1111   0  0  0   0             可知如果n为奇数则结果为8n+8如果为偶数则为8n+16
           
原创粉丝点击