前言
- 通过让编译器产生机器级程序的汇编表示,我们了解编译器和它的优化能力,以及机器代码、它的数据类型和它的指令集。当编写能有效映射到机器上的程序时,了解编译器的特性会有所帮助,一些高级语言会抽象隐藏有关程序的重要细节。理解程序是如何映射到机器上的,会让理解这些存储之间的区别容易一些。
- 汇编语言与C代码差别很大,在汇编语言程序中,各种数据类型之间的差别很小。程序是以指令序列来表示的,每条指令都完成一个单独的操作。部分程序状态,如寄存器和运行时栈,对程序员来说是直接可见的。仅提供了低级操作来支持数据处理和程序控制。编译器必须用多条指令来产生和操作各种数据结构,来实现像条件、循环和过程这样的控制结构。
知识简梳理
机器级代码
两种抽象
指令集体系结构(ISA)
定义了处理器状态、指令的格式,以及每条指令对状态的影响。
虚拟地址
机器级程序使用的存储器地址是虚拟地址,虚拟地址是多个硬件存储器和操作系统软件的抽象。虚拟地址空间由操作系统负责管理并进行相关翻译(抽象至物理的映射)。
函数调用过程
示意如图:
用户栈
栈向低地址方向增长,而栈指针%esp指向栈顶元素
寄存器
程序寄存器组:唯一能被所有函数共享的资源
寄存器使用惯例:当过程P调用Q时,Q可以覆盖这些寄存器
指令
转译控制类
call Label | 过程调用
call | *Operand 过程调用
leave | 为返回准备栈
ret | 从过程调用中返回
缓冲区溢出
- 【推荐教学博客】
- 由于C/C++语言没有数组越界检查机制,当向局部数组缓冲区里写入的数据超过为其分配的大小时,就会发生缓冲区溢出。
- 实验
实验
抗缓冲区溢出攻击
- 栈随机化
- 栈破坏检测
- 限制可执行代码区域