前言:
最近的事情确实有点多,越学习,感觉自己差的越远,需要不断的努力才能追上与大牛的差距,希望自己能不断的保持学习的劲头,一直这样进步下去。
我的github:
我实现的代码全部贴在我的github中,欢迎大家去参观。
https://github.com/YinWenAtBIT
第三章:
汇编代码:
一、3.3-3.6节:
这一部分的主要讲述的就是汇编代码的语法格式以及寄存器的操作,寻址与各种条件语句。
这一部分的内容在大部分的书上都能学习到,比较重要的一点就是该部分给出了许多的练习,做完了练习能对汇编更加的熟悉,对C转汇编的了解会更有底气。该部分需要说的不多,学完了相当于又熟悉了一遍汇编语言。
二、3.7节,过程:
这一部分重点在介绍栈在程序调用时候怎么保存程序信息,并在程序运行结束之后恢复原有的变量。
1.栈帧结构:
每一个过程,或者说是每一个子程序,都会被分配一部分栈,那一部分叫做栈帧。底部是由帧指针%ebp指向的地址,该地址中保存着上一个子程序的栈帧底部,也就是上一个%ebp的值,顶部是栈指针%esp指向的地址。这两个指针之间的栈,就是该子程序的栈帧。
注意栈的增长是从高地址往低地址增长的,那么%ebp的地址必然大于%esp指向的地址。
2.返回地址:
每一个程序调用子程序的时候,就会需要保存下正在运行的程序的信息,首先,下一条指令的执行的地址,也就是我们所说的返回地址,通过压栈保存,这个地址将会在子程序返回的时候,由程序计数器PC来读取。返回地址压栈之后,再压栈%ebp,这也就是调用子程序的程序的帧栈底部了。如果还有少量需要被调用者保存的寄存器,将会由被调用者再返回的时候复原。
三、3.8节,数组分配与访问:
在C语言中,数组的分配只能使用常数来确定数组的大小,运行过程中的动态分配需要在heap中分配空间。
局部变量的数组将在栈中被分配。
嵌套的数组是指多维的数组,比如二维数组,三维数组。
但是多维数组的本质上还是一维的数组,只不过C语言在编译的时候会将多维数组的操作变为对一维数组的操作。
四、3.9节,异质的数据结构:
1.结构,struct
结构的地址也是结构中第一个元素的地址。并且由于字节对其的要求,其中可能会有空出来空间。
数据对齐的要求是:一般来说某种对象的地址必须是其字节大小的倍数。
Linux中2字节的数据对齐2,int, float, double 都对齐4。
Windows中要求都是其大小的倍数。
五、3.12节,存储器越界引用与缓冲区溢出:
如果程序在使用数组时,不对边界进行检查,那么很有可能,越界的信息会覆盖栈中的返回地址,导致程序无法返回的错误。
更甚的是,如果被人恶意覆盖了返回地址,那么程序返回的时候可能去执行本来不应该执行的程序。这就是攻击代码。
对抗缓冲区溢出的方式:
1.栈随机化,这样要插入的代码的地址便是不可确定的,这样攻击者就难以实施攻击。
2.栈破坏检测:如果在程序运行的过程中,栈被破坏,那么程序将会终止。
3.限制可执行代码的区域:这个很好理解,不会返回到不该执行的代码地址
五、3.13,节,X64的汇编代码
x64的情况主要是寄存器变多了,寄存器大小变大了,有一些函数调用甚至不再需要压栈来完成,可以直接用足够的寄存器计算出结果。其他的部分与x86的差别不是特别大。
总结: