csapp-第三章-程序的机器级表示
程序编码
- 反汇编器是通过机器代码文件中的字节序列来确定汇编代码的。有着特点的机器码,例如:E8就代表call指令
数据格式
- 字—word,双字节—double words ,四字节—quad words
访问信息
- 一般局部变量是放在寄存器中的,而不是内存中,因为访问寄存器比访问内存要快得多
- 栈是一种数据结构,可以添加或者删除数据,但是必须遵守的是“先进后出原则”。相当于一个口管理进出,而这个删除和存入的这一个口,我们叫栈顶。
算数和逻辑操作
- lea为加载有地址,作用是从内存读取数据到寄存器中。作用就是取地址。
- 一元操作与二元操作,就是有几个操作数的意思,比如,++i,就是一元,x+Y,就是二元。
- test与and 的作用都是进行逻辑与的运算,test与and 的区别,test不会改变ax与bx的值,而and是ax与bx计算之后,然后将值存储在ax中。
- 跳转表是一个数组,表项i是一个代码段的地址,起到索引的作用。用跳转表的一大优点就是执行开关语句的时间与开关情况的数量无关。意思就是,判断一次,然后就直接执行了,而像if–else这类,就需要分别进行判断,然后才能执行。
数组分配和访问
-
c语音允许指针进行运算,,*运算和&运算, *与&是可以相互抵消的。
-
二维数组在内存中排列的顺序是按照行优先的原则。列如数组A [5] [3]
这里可以联想到,一个一维数组可以省略其大小,而二维数组可以省略其行,但是不能省略其列。此时二维数组就可以看做一维数组的嵌套,一维数组必须声明其为什么数组,以表明其装载的数据是int还是char,表明其存储数据的大小,同理二维数组,一维数组的数组,使用里面的数组我们必须表明其大小,而一维数组的大小就是其有多少个数据,因此代表里层数组大小,也就是二维数组的列不能省略。
异质的数据结构(c语言中的结构体和联合体)
-
结构体 将可能不同类型的对象聚合到一个对象中。结构体的所有组成部分都存放在内存的连续的区域内,指向结构体的指针是结构体第一个 字节的地址
-
联合体 允许多种类型来引用一个对象,一个联合体的总大小为其最大字段的大小
-
数据对齐 计算机系统要求某种类型对象的地址必须为2、4、8的倍数。(对于x86指令来说,保持数据对齐能提高效率)
-
大多数函数的栈帧的边界都必须是16字节的倍数
-
-
在Linux系统中,栈随机化已经变成了标准行为,通过栈随机化使得栈的位置在程序每次运行时都有变化,以避免安全单一化。
-
栈破坏检测。栈保护者机制,在栈帧中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀值,由程序运行时随机产生。原理是,在恢复寄存器和从函数返回之前,程序会检测金丝雀值是否被函数某个操作改变,若改变,程序便会异常终止。(一般用于栈溢出)
浮点代码
- 把浮点值转换成整数时,指令会执行截断,把值向零进行舍入