计算机系统课程 笔记总结 CSAPP第三章 程序的机器级表示(3.8-3.10)

3.8.1 基本原则

数据类型T和整形常数N,声明:

  • T A[N]
  • 在内存中分配 L×N 字节的连续区域(L是数据类型T的大小)
  • 起始位置表示为 Xa ,标识符 A 作为数组开头的指针
  • 数组元素 i 会被存放在地址为 Xa+L×i的地方

 

 

 

 

 

 

 

 

 

 

 

 

例如,假设E是一个int型的数组,而我们想计算E[i],E的地址存放在寄存器%rdx中,而i存放在寄存器%rcx中。然后,指令

  • movl (%rdx, %rcx, 4), %eax

会执行地址计算,读这个内存位置的值。

3.8.2 指针运算

3.8.3 嵌套的数组

 

 

 

 

 

 

 

 

 

 

二维数组声明:

 

 

 

 

 

 

 

 

 

 

 

 

 

3.8.4 定长数组

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

优化

 

 

 

 

 

 

 

 

 

 

 

最后一个元素存在 &B[N-1][k] 则 &B[N][k] 为终止地址

 

 

 

 

 

 

 

 

 

 

  • 移动到下一列,地址加4(int)
  • 移动到下一行,地址加4*N

 

 

 

 

 

 

 

 

3.8.5 变长数组

例如要访问n×n数组的元素i,j,我们可以写一个如下的函数:

参数n必须在参数A[n][n]之前,这样函数就可以在遇到这个数组的时候计算出数组的维度。


3.9 异质的数据结构

  • 结构 structure
    • 关键字:struct
  • 联合 union
    • 关键字:union

3.9.1 结构 struct

  • C语言的struct声明创建一个数据类型,将可能不同类型的对象聚合到一个对象中。
  • 类似于数组的实现,结构的所有组成部分都存放在内存中一段连续的区域内,而指向结构的指针就是结构第一个字节的地址
  • 编译器维护关于每个结构类型的信息,指示每个字段(field)的字节偏移
  • 它以这些偏移作为内存引用指令中的位移,从而产生对结构元素的引用。

3.9.2 联合 union

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 对于类型 union U3 * 的指针p, p->c, p->i[0], p->v 引用的都是数据结构的起始位置
  • 一个联合总的大小等于它最大字段的大小

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

即:指针/数据 二选一

 

 

 

 

 

 

 

 

 

优化空间

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 访问不同数据类型的位模式
  • 强行转换类型

 

 

 

 

 

 

 

 

 

 

 

 

  • 字节顺序问题很重要
  • 小端法与大端法得出的 double d 不同

 

 

 

3.9.3 数据对齐

 

 

 

 

 

 

 

 

  • 许多计算机系统要求某种类型对象的地址必须是K(通常是248)的倍数
  • 这种对齐限制简化了形成处理器和内存系统之间接口的硬件设计。
  • 无论数据是否对齐,x86-64硬件都能正确工作。
  • 编译器在结构体中插入空白,以确保字段的正确对齐

 

 

 

 

结构体数组:

7字节留白

 

 

 

 

 

 

 

 

 

优化空间

 

 

 

 

 


3.10 在机器级程序中将控制与数据结合起来

3.10.1 理解指针

特点/原则

  1. 每个指针都对应一个类型
  2. 每个指针都有一个
  3. 指针用‘&’运算符创建
  4. *’操作符用于间接引用指针
  5. 数组与指针紧密联系
  1. 将指针从一种类型强制转换成另一种类型,只改变它的类型,而不改变它的值
  1. 指针也可以指向函数(函数指针???)

3.10.2 应用:使用GDB调试器

  • quit 退出
  • run 运行(在此行给出命令行参数)
  • kill 停止程序
  • break multstore 在函数multstore入口处设置断点
  • break * 0x400540 在地址0x400540处设置断点
  • delete 1 删除断点1
  • delete 删除所有断点
  • stepi 执行1条指令
  • stepi 4 执行4条指令
  • continue 运行到当前函数返回
  • disas 反汇编当前函数
  • print $rax 以十进制输出%rax内容
  • info frame
  • info register
  • help

3.10.3 内存越界引用和缓冲区溢出

  • gets()函数无法确定是否为保存整个字符串分配了足够的空间
  • strcpy, strcat: 任意长度字符串的拷贝
  • scanf, fscanf, sscanf, 使用 %s 转换符时
  • 缓冲区溢出,返回地址被破坏,程序看起来能工作
  • 缓冲区溢出使程序执行它本来不愿意执行的函数,这是最常见的通过计算机网络攻击系统安全的方法

 

 

 

 

 

 

 

 

 

  • 输入字符串包含可执行代码的字节序列
  • 将返回地址 A用缓冲区B的地址替换
  • 当Q执行ret后,将跳转到B,执行漏洞利用程序(exploit code)

 

 

 

3.10.4 对抗缓冲区溢出攻击

针对缓冲区溢出攻击:

  • 避免溢出漏洞(函数、代码细节)
    • fgets代替gets、strncpy代替strcpy
    • scanf函数中别用%s(或用%ns代替%s,其中n是一个合适的整数)
  • 使用系统级的防护
    • 3.10.4.1 栈随机化(随机的栈偏移)
      • 程序启动后,在栈中分配随机数量的空间

  • 将移动整个程序使用的栈空间地址
  • 黑客很难预测插入代码的起始地址
  • 例如:执行5次内存申请代码
    • 每次程序执行,栈都重新定位
  • 3.10.4.3 限制可执行代码区域(非可执行代码段)
    • 目的:消除攻击者向系统中插入可执行代码的能力
    • 在传统的x86中,可以标记存储区为“只读”或“可写的”
    • x86-64添加显式“执行”权限
    • 将stack标记为不可执行(漏洞利用程序exploit code

  • 3.10.4.2 栈破坏检测(栈金丝雀)
    • 编译器使用“栈金丝雀”(stack canaries)
      • 在栈中缓冲区(buffer)之后的位置放置特殊的值——金丝雀(canary)
      • 退出函数之前,检查是否被破坏
    • 用GCC实现
      • -fstack-protector
      • 该选项现在是默认开启的(早期默认关闭)

 

另:

3.10.5 支持变长栈帧

有些函数需要的局部存储是变长的(例如alloca函数)

%rbp 帧指针/基指针

base pointer --> bp

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《计算机系统 第三版》是一本经典的计算机系统概念教材,其中的习题是帮助读者加深对计算机系统原理的理解和应用的工具。以下是对该书的习题的回答。 在《计算机系统 第三版》的习题中,涵盖了计算机系统的多个方面,包括计算机体系结构、操作系统、存储器系统、并发控制、网络通信等。这些习题的目的是帮助读者巩固对教材内容的理解,并通过实践问题的解决来培养解决复杂问题的能力。 举例来说,其中的习题可能包括: 1. 计算机系统体系结构的习题:如理解多存储器体系结构的原理,设计一个具有多缓存的计算机系统,并对性能进行评估。 2. 操作系统习题:如深入理解进程管理和线程管理的概念,编写一个多线程的程序,并通过调试和性能分析优化程序。 3. 存储器系统习题:如设计一个虚拟内存系统,讨论页表大小对页面错误率的影响,以及页表的压缩和局部性原理。 4. 并发控制习题:如理解并发控制的一致性和可见性概念,讨论分布式系统中多个进程的并发访问共享资源的问题,如何保证数据一致性。 5. 网络通信习题:如深入理解网络协议的工作原理,设计一个网络协议的通信实验,并进行性能测试与分析。 通过解答这些习题,读者可以加深对计算机系统原理的理解,并且培养解决实际问题的能力。同时,通过实践习题,读者能够更好地应用所学知识,加强计算机系统的实际应用能力。 ### 回答2: "计算机系统 第三版 csapp"是由深入了解计算机系统设计与实现的大师教材。在这本书中,习题是重要的一部分,旨在帮助读者巩固和扩展他们对所学知识的理解。下面是对该书习题的一些回答和解释。 习题的目的是让读者进一步思考和实践书中所介绍的主题。这些习题包括了各个层面的知识点,例如机器代码、汇编语言、处理器体系结构、内存层次结构、并发控制、网络编程等等。回答这些习题需要读者对这些主题有着清晰的理解和运用能力。 在回答习题时,读者应该从书中对应的章节中找到相关的信息来辅助解答。这有助于加深对知识点的理解,并且提高问题解决的效率。另外,在解答习题时,也可以参考书中的例子和实验,这样能更好地应用所学知识。 对于习题解答的思路,首先要仔细阅读题目,并且理解问题的要求。其次,要分析问题,找出解决问题所需的关键知识和技巧。然后,运用所学知识和技巧来解答问题,并进行验证和检查。最后,总结解题过程,并且思考问题的拓展和应用。 解答习题需要耐心和毅力。有些习题可能涉及到复杂的概念和技术,需要更多的时间和努力来理解和解答。但通过习题的实践和思考,读者可以更加深入地理解计算机系统的运作原理,提高解决问题的能力。 总之,“计算机系统 第三版 csapp”的习题是深入学习计算机系统设计与实现的重要途径,通过回答习题可以加深对知识点的理解,并提高自己解决问题的能力。在解答习题时,读者需要仔细阅读题目,理解问题的要求,分析问题,并运用所学知识和技巧来解答。通过实践和思考,读者可以更好地理解计算机系统,并提高自己的技术水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值