• 第三章 机器的程序级表示(下)


    数据传送:

    当过程P调用过程Q时,P的代码必须首先把参数复制到适当的寄存器中。类似的,当Q返回到P时,P的代码可以访问寄存器中的返回值;

    每个过程调用在栈中都有它自己的私有空间,因此,多个未完成调用的局部变量不会相互影响。当过程被调用时分配局部存储,当返回时释放存储;

    数组的分配和访问:

    对于数据类型T和整型常数N,数组表现形式如下:T A[N]。它表示在内存中分配一个L*N字节的连接区域,这里L是数据类型T的字节大小。当然,A也可以用来作为指向数组开头的指针。如:

    char A[12];

    char *B[8];

    声明一个数组 T D[R][C],它的数组元素D[i][j]的内存地址为: D地址 + L( i * C + j )

    比如,int A[5][3],其中,C的值即列数3,L即int类型的字节长度4,所以,数据元素A[i][j] 的内存地址为:A数据地址 + 4*(3*i+j)

    定长数组:当程序要用一个常数作为一个数组的维度或者缓冲区的大小时,最好通过#define声明这个常数与一个名字联系起来,然后在后面一直使用这个名字来替代常数的值。这样,如果需要修改这个值,直接改这个#define声明就好了。如

    #define N 16;

    typedef int fix_matrix[N][N];

    变长数组:数组在被分配时才计算出来数组长度大小,一般都是使用malloc这种函数来为这些数组分配存储空间;如,int A[expr1][expr2],如果A数组作为一个函数参数,那么,在调用函数,遇到这个声明的时候,通过对表达式exp1和exp2求值来确定数组的维度;

    异质的数据结构:

    使用struct来声明,将可能多个不同类型的对象聚合到一个对象中。如:

    缓冲区溢出:C对于数组引用不进行任何边界检查,而且局部变量和状态信息都是存放在栈中。这两种情况结合到一起就能导致严重的程序错误,对越界的数组元素的写操作会破坏存储在栈中的状态信息。通常,当栈中分配某个字符数组来保存一个字符串,但是字符串长度超出了为数组分配的空间。

    对抗缓冲区溢出攻击机制:

    1.栈随机化

    2.栈破坏检测;

    3.限制可执行代码区域;

    上面的方法都是由编译器或操作系统完成的,无需程序员主动关心。

  • 相关阅读:
    Java 编译器
    ElasticSearch 集群搭建
    致:奋斗路上的自己
    ElasticSearch 简单入门
    char* 和 char* const
    usb虚拟网卡与串口
    usb虚拟网卡与串口
    ethtool处理网卡不断重启
    客车网上订票系统项目--票务管理、前端个人信息修改
    mysql错误号码2003 can't connect to mysql server on 'localhost' (0)解决方案
  • 原文地址:https://www.cnblogs.com/sunnyDream/p/9978253.html
Copyright © 2020-2023  润新知