1. GCC是GNU开发的编译器,Linux下的标准编译器即GCC,GCC在Linux下编译汇编程序,汇编程序使用Linux下的AT&T汇编(即GNU as汇编,AT&T汇编也只用在Linux下);
或者说写arm汇编指令时在Linux下使用AT&T汇编语法,这时写出的汇编程序可以用Linux下的GCC作为编译器;
在Linux下的GCC下编译C语言程序,若在此C语言程序中使用内嵌汇编代码须使用GCC内嵌汇编;
写80x86汇编指令时在Windows下使用INTEL汇编语法,此时写出的汇编程序可以使用Windows下的NASM作为汇编器;
2. 对于已指定初始值的全局变量和静态局部变量,在程序开始时分配存储空间到数据段(.data段)并初始化;
对于未指定初始值的全局变量和静态局部变量,在程序开始时分配存储空间到BSS段(.bss段),未指定值初始化但BSS段会自动清零,所以未指定初始值的全局变量和静态局部变量看起来使用默认的零值初始化了
对于动态局部变量(程序中临时创建的变量)在程序开始时并未分配存储空间,在调用其所在函数时才动态的分配存储空间到栈
由上可见,数据段,BSS段,堆,栈还有代码段都是一块内存区域,是硬件,在程序由硬盘读到内存时被使用,其中数据段,BSS段和代码段在程序开始时静态分配内存,属于静态存储区,堆和栈在动态临时局部变量创建时(即函数被调用时)动态分配内存,属于动态存储区
静态局部变量(无论指未指定初始值)在函数调用时已有初始值,不再在函数调用时执行初始化语句,当然对它的赋值语句依然执行。
对于非静态局部变量,当其所在函数被调用时,这时栈会给函数中所有定义的非静态局部变量分配空间,无论此变量有没有初始值,栈给函数分配的空间可能大于函数所需的空间,会造成一定的空间浪费,有一部分空间浪费是由于字节对齐造成的,当函数结束时释放这些空间。
对于函数中的char *p = "abcd";其中p存储在栈中,字符串常量存储在常量区,并不在栈中占存储空间;
又如:char str[8] = "asdfg";其中字符串常量也是存储在常量区,并不在栈中占存储空间,但与p不同的是str[8]存储在栈中,占8个字节;
对于int i = 0;其中的常数0则和代码一起存储在代码段
3. 地址倒数一位始终为零,则所有地址均为2的倍数;始终倒数两位为零,则所有地址均为4的倍数;始终倒数三位为零,则所有地址均为8的倍数;
综上,如果地址始终要求倒数n位为零,则其中所有地址均为(2^n)的倍数。
4. 在Windows下VC6.0编译环境中,栈的默认对齐是四字节对齐,所以在此环境下两个字符型变量(不管是作为局部变量还是函数参数)在栈中要占8个字节;
在Linux下GCC编译环境中,栈在给局部变量分配空间时的默认对齐是一字节对齐,而函数的参数入栈时默认对齐是四字节对齐,所以两个字符局部变量占2个字节,两个字符变量作为函数参数入栈时要占8个字节;
在Linux下GCC编译环境中,当入栈的函数固定参数不是四字节的时候,栈会给此参数重新分配空间,造成函数固定参数和可变参数在栈中的位置不连续,固定参数之间的位置顺序也将与入栈时不同,这将使得无法实现变参函数,在Windows下VC6.0中没有这种情况;
在Linux下GCC编译环境中,栈指针esp必须是16的整数倍(andl %-16, %esp),即16字节对齐,而在Windows下VC6.0编译环境中无这一要求;
函数里面定义的变量是默认对齐方式----变量首地址是自身结构体里边最大标准数据类型字节的整数倍。
阅读(1007) | 评论(0) | 转发(0) |