资源描述:
《cc++深层探究》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、1.字节序inti=0x00000041;char*p=(char*)&i;printf("...%s...",p);上面的代码在x86下结果是A,但是在其他平台下结果不一定,有可能并不会执行输出。其原因是在IA32下的字节序是:0X41000000;但是在其他平台下字节序可能会是这样:0000000X41,所以不能保证这样的转换具有正确性。这就是所谓的大端组织和小端组织。2.调用栈voidfun(charlove,char*p){}int_tmain(intargc,_TCHAR*argv
2、[]){charlove='y';char*p="loveyou?";fun(love,p);return0;}//GcccallStack.cpp-S//CatcallStack.sAsm如下:.file"callStack.c"gcc2_compiled.:___gnu_compiled_c:.text.align4.globl_fun//表示函数是全局可见的。.def_fun;.scl2;.type32;.endef_fun:pushl%ebpmovl%esp,%ebpsubl$16,%e
3、spmovl8(%ebp),%eaxmovb%al,-1(%ebp)L1:movl%ebp,%esppopl%ebpret.def___main;.scl2;.type32;.endefLC0:.ascii"loveyou? ".align4.globl_main//表示函数是全局可见的。.def_main;.scl2;.type32;.endef_main:pushl%ebpmovl%esp,%ebpsubl$16,%espcall___mainmovb$121,-1(%ebp)movl$L
4、C0,-8(%ebp)movl-8(%ebp),%eaxpushl%eax//参数入栈movsbl-1(%ebp),%eaxpushl%eax//参数入栈call_fun//调用funaddl$8,%espxorl%eax,%eaxjmpL2.p2align4,,7L2:movl%ebp,%esppopl%ebpRet所以调用函数分为两个步骤:第一:将参数入栈第二:将指令执行点转移到函数代码的入口通常,先压栈的内容存放在高地址区域,后压栈的内容在低地址区域。需要注意:1)C语言标准并没有规定参数
5、入栈的顺序,至于从右到左还是从左到右,这由编译器厂商决定。但是vc和gcc测试结果表明其都是从右到左。2)gcc和vc默认的汇编代码是使用ebp寻址的,esp解释了整个函数的栈空间。3.变量的可见范围和生存周期voidfun(){intb=100;}intmain(){intb=20;fun();return0;}为什么fun里面的b不能访问main的b?这是因为函数在调用之前,编译器不可能知道知道这个函数的内部变量的准确地址,变量是直到到达函数内部时才通过在栈里面规划出空间从而宣告自己的真实存
6、在。函数一旦结束,执行点马上返回,esp被重新调整,原来栈里面的内容就不存在了。也就说这是两个不同的栈,会进行栈的切换。所以一个栈消失后肯定不能再继续访问。其次,参数也是调用函数前才放到栈里面,所以函数返回后会消失,所以参数和内部变量有相同的可见范围。第三,main调用fun传递了b,并不会导致b的值被改变,因为调用fun的时候是把b的值压栈,并不是把b的地址压栈,fun并不知道b的地址。第四,外部变量地址分配:由于外部变量在整个程序运行期间的地址不能改变,所以不可能放到栈里面,只能是在数据段中
7、。所以这些数据的地址在程序进行链接的时候才能准确得出,另外该地址从程序开始运行到结束都是固定的,所以任何函数都能存取这些数据。intglobal;voidfun(){intlocal=4;externintglobal2;//由于其定义出现在fun后面,所以必须有一个声明(参见asm码);global=5;//由于global出现在fun之前,所以函数知道其地址,不需要声明global2=6;return;}intmain(){intglobal;global=20;fun();return0;
8、}Asm如下;.file"callStack.c"gcc2_compiled.:___gnu_compiled_c:.text.align4.globl_fun.def_fun;.scl2;.type32;.endef_fun:pushl%ebpmovl%esp,%ebpsubl$16,%espmovl$4,-4(%ebp)movl$5,_globalmovl$6,_global2jmpL1.p2align4,,7L1:movl%ebp,%esppopl%ebpret.def___main;.s