CC++深层探究.pdf

  1. 1、本文档共36页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
CC深层探究

1.字节序 int i = 0 char *p = (char*)i; printf(... %s ...\n,p); 上面的代码在x86下结果是A,但是在其他平台下结果不一定,有可能并不会执行输出。其 原因是在IA32下的字节序是:0X41 00 00 00 ;但是在其他平台下字节序可能会是这 样: 00 00 00 0X41,所以不能保证这样的转换具有正确性。这就是所谓的大端组织和小 端组织。 2.调用栈 void fun(char love,char *p) { } int _tmain(int argc, _TCHAR* argv[]) { char love = y; char *p = love you?; fun(love,p); return 0; } //Gcc callStack.cpp -S //Cat callStack.s Asm如下: .file callStack.c gcc2_compiled.: ___gnu_compiled_c: .text .align 4 .globl _fun //表示函数是全局可见的。 .def _fun; .scl 2; .type 32; .endef _fun: pushl %ebp movl %esp,%ebp subl $16,%esp movl 8(%ebp),%eax movb %al,-1(%ebp) L1: movl %ebp,%esp popl %ebp ret .def ___main; .scl 2; .type 32; .endef LC0: .ascii love you?\0 .align 4 .globl _main //表示函数是全局可见的。 .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp,%ebp subl $16,%esp call ___main movb $121,-1(%ebp) movl $LC0,-8(%ebp) movl -8(%ebp),%eax pushl %eax //参数入栈 movsbl -1(%ebp),%eax pushl %eax //参数入栈 call _fun //调用fun addl $8,%esp xorl %eax,%eax jmp L2 .p2align 4,,7 L2: movl %ebp,%esp popl %ebp Ret 所以调用函数分为两个步骤: 第一:将参数入栈 第二:将指令执行点转移到函数代码的入口 通常,先压栈的内容存放在高地址区域,后压栈的内容在低地址区域。 需要注意: 1)C语言标准并没有规定参数入栈的顺序,至于从右到左还是从左到右,这由编译器厂 商决定。但是 vc和gcc测试结果表明其都是从右到左。 2)gcc和vc默认的汇编代码是使用ebp寻址的,esp解释了整个函数的栈空间。 3.变量的可见范围和生存周期 void fun() { int b = 100; } int main() { int b = 20; fun(); return 0; } 为什么fun里面的b不能访问main的b?这是因为函数在调用之前,编译器不可能知道知道 这个函数的内部变量的准确地址,变量是直到到达函数内部时才通过在栈里面规划出空间从 而宣告自己的真实存在。函数一旦结束,执行点马上返回,esp被重新调整,原来栈里面的 内容就不存在了。也就说这是两个不同的栈,会进行栈的切换。所以一个栈消失后肯定不能 再继续访问。 其次,参数也是调用函数前才放到栈里面,所以函数返回后会消失,所以参数和内部变量有 相同的可见范围。 第三,main调用fun传递了b,并不会导致b的值被改变,因为调用fun的时候是把b的值压 栈,并不是把b的地址压栈,fun并不知道b的地址。 第四,外部变量地址分配:由于外部变量在整个程序运行期间的地址不能改变,所以不可能 放到栈里面,只能是在数据段中。所以这些数据的地址在程序进行链接的时候才能准确得出, 另外该地址从程序开始运行到结束都是固定的,所以任何函数都能存取这些数据。 int global; void fun() { int local = 4; extern int global2;//由于其定义出现在fun后面,所以必须有一个声明(参见asm 码); globa

文档评论(0)

xxj1658888 + 关注
实名认证
内容提供者

教师资格证持证人

该用户很懒,什么也没介绍

领域认证该用户于2024年04月12日上传了教师资格证

1亿VIP精品文档

相关文档