《CSAPP》程序的机器表示——汇编代码与C的联系

本文介绍了《CSAPP》第三章关于汇编代码和C语言的联系,包括汇编语法、过程调用中的栈帧结构、数组分配与访问、异质数据结构和存储器越界引用。重点讨论了栈帧如何保存和恢复程序信息,以及缓冲区溢出的防御措施。同时提到了X64架构下的变化。
摘要由CSDN通过智能技术生成

前言:

     最近的事情确实有点多,越学习,感觉自己差的越远,需要不断的努力才能追上与大牛的差距,希望自己能不断的保持学习的劲头,一直这样进步下去。

我的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的差别不是特别大。

总结:

熟悉汇编代码还是非常的重要的,通过这一部分的学习,我彻底理解了C代码时如何变成汇编代码的。也能通过汇编代码级别的思考,来尝试优化我的C程序。
栈帧过程也是一个非常重要的过程,这一部分学习之后,基本上理解了程序调用过程,以及代码是如何执行的。对理解计算机的运行过程非常有帮助。
内存模型也同样如此。理解了之后能够更加自如的进行调试,错误分析。总之,深入底层了解计算机确实是非常有必要的一件事。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值