1.正溢出与负溢出: 首先,一个正数与一个负数相加,不可能溢出,因为结果的绝对值一定小于两个加数的绝对值,既然两个加数能合理表示出来,结果一定也能合理表示出来. 其次,正溢出是由于两个很大的正数相加,导致符号位变成1的情况如0110+0011=1001(假设最大只能运算4位) 负溢出则是两个很小的负数相加,导致符号位变成0的情况,如1011(-5)+1011(-5)=10110->0110溢出,如1111(-1)+1111(-1)=11110->1110则没溢出. 因此,正溢出的判断标准是符号…
1.算术和逻辑操作类指令分四类:加载有效地址,一元操作,二元操作和移位,如下: 2. leaq指令,类似mov指令,它左侧的数看似是给出一个地址,在内存中从给定的地址取操作数,传给右边的目的地.但其实没有取,而是直接将左侧的数对应的地址传给了右侧的目的地. 例子: leaq 7(%rdx,%rdx,4),%rax 若%rdx的值为x,则最后%rax的值为5x+7,而不是以5x+7为地址,在内存中寻址得到的操作数 3. 第二组是一元指令,目的地为寄存器或一个内存位置,具体不用介绍,看表就好. 4.…
1.如何由机器代码生成汇编代码? objdump -d再加上文件名即可直接在终端看到由反汇编器恢复的汇编代码.注意,文件名并不一定得是.o文件,任何可执行文件都可以. 结果如下: 仅列举了反汇编test.o的结果,其它的也测试过,不放图了. 2. 32位和64位的基本数据类型大小对比: 32位: char:1字节,char*:4字节,short int:2字节,int:4字节,unsigned int:4字节,float:4字节,double:8字节,long:4字节,long long:8字节…
gcc是一种C编译器,这次我们根据书上的代码尝试着使用它. 使用之前,先补充前置知识.编译器将源代码转换为可执行代码的流程:首先,预处理器对源代码进行处理,将#define指定的宏进行替换,将#include包含的文件插入,随后,编译器生成源文件对应的汇编代码,以.s结尾.然后汇编器会将汇编代码转换为机器代码,以.o结尾,最后,链接器将多个机器代码(如果有多个的话)以及代码中用到的库函数(如printf)合并,产生可执行文件. 若要比较详细地了解gcc常用参数,可以参考这篇文章: https:/…
一.几个关于指针的小知识点: 1.  malloc是在堆上动态分配内存,返回的是void *,使用时会配合显式/隐式类型转换,用完后需要用free手动释放. alloca是标准库函数,可以在栈上分配任意字节数量的内存,用完自动释放. 2.指针的优先级较低: char (*p)[3],括号中优先级最高,所以p是一个指针,指向一个3个元素的char数组. char *p[3],  因为指针优先级较低,所以*与char结合,p代表一个3个元素的数组,每个元素都是一个char *. 3.函数指针: 它的…
1.基本结构: 如上图所示,是通用的栈帧结构.大致分两块,调用者函数P和被调用者函数Q. 对P来说,要做的工作是把传递参数中多于6个的部分压栈,随后把Q返回时要执行的下一条指令的地址压栈. 对Q来说,要做的工作分3块,一是将要保存寄存器的值压栈,二是将要保存的局部变量压栈,三是把多余参数压栈.刚看到这里你可能不懂,没关系,接下来会分别介绍这3块. 2.参数构造部分: 首先介绍参数构造部分,其实它就对应调用者函数P的多余参数压栈操作,因为函数调用一环套一环,P调用Q,Q可能调用R,当Q调用R时,若…
1.数据对齐 为什么要对齐:通俗点解释就是CPU对数据访问时,每次都是取固定数量的字节数,假如一次取4个字节,若有个int存在0x01-0x04,则一次就能取出,若存在0x03-0x06,则需要分两次才能取到(第一次0x01-0x04,第二次0x05-0x08),这样会降低CPU效率,更何况还有像short,char之类的不是4个字节的数据.因此,编译器会对数据进行强制对齐. 对齐规则: 1.任何K字节的基本对象的地址必须是K的倍数 2.在结构末尾根据需要会做一些填充,使其一旦被拓展为数组时可以…
这一节比较简单,仅记录几个比较重要的点: 1.C语言允许对指针进行运算,计算出的值会根据该指针引用的数据类型大小进行伸缩. 例子: 其中,xE是数组的起始地址.注意,指针运算时,若最终结果为指针,则指针的值会根据引用的数据类型进行拉伸.若最终结果为数值,则结果会被压缩,如最后一行所示,算出的结果不是4i,是4i/4=i. 2.对于多维数组,以二维数组为例,如int A[5][3],实际上等价于:typedef int row3_t[3];  row3_t A[5]; 此外,数组元素在内存中存储时…
仅从寻址上看,32位和64位机器能寻址的内存空间大小不同. 需要知道的是,计算机系统对存储器作了抽象,程序“认为”内存是一个很大的字节数组,然而实际上它是由多个硬件存储器和操作系统组合起来实现的. 程序看到的内存地址是虚拟地址,是操作系统为了让程序使用方便作的映射,实际当程序运行时,要从某个地址取信息时,需要由操作系统作一层映射,将虚拟地址转换为实际内存的物理地址.这样,程序方就可以不用管底层的细节,只需要“认为”内存是个很大的字节数组,用就完事了. 32位机器能寻址的内存空间是232个字节,大…
作为一个测试团队,基本的职责是:测试产品,发现缺陷,报告结果,使每个版本的测试水准稳步提升.这些价值是作为一个测试所必须具备的,发挥这些价值能够让测试获得研发团队的基本信任.这类价值分为3部分: 1)拦截缺陷,即对产品进行测试,尽可能把产品的缺陷拦截在研发阶段.2)提供数据,即提供产品的质量结论,并且给出支撑这些结论的数据.3)测试过程可控,提升测试团队和测试工程师的能力,使得产品测试的效率.质量.成本都处于可控状态. “扫门前雪”说明这些价值基本上是测试的本职工作,价值的发挥是依靠测试自身或者…