关于指针、内存的一些释疑与疑问

1、变量名是内存地址的别名

int val3 = 2;
*(int *)&val2 = 2; // 汇编代码完全一致。先取地址,再对地址对于内存赋值

我觉得是编译器直接优化掉了中间过程,直接往栈上内存写值。

*(int *)&val2 = 2;

而如果取地址,再赋值的话,会有额外的指令操作:

  • “lea     rax, [rbp-16];将rbp-16这个值直接赋给rax,而不是把rbp-16处的内存地址里的数据赋给rax”。先把val1的地址[rbp - 16],放进寄存器rax中。(mov rax,[rbp - 16]则是把内存地址为rbp - 16处的数据赋给rax)
  • 再把 rax中的地址值,赋值给p1,p1对于栈位置[rbp - 8]
  • 再把p1的值放到寄存器中rax
  • 再对rax中地址的值,写入2

这里为什么需要寄存器rax参与?

针对第五条汇编,lea指令加载有效地址(load effective address),从内存读取数据到寄存器(是不是一定要用寄存器,可不可以直接就把地址给[rbp - 8]???,再直接向[rbp - 8] 赋值为2???)

2、暴露指针的风险

如果代码中暴露了代码的地址(变量、函数),我们都可以直接通过该地址来改写这块内存的内容。如果没有硬件的限制,如MMU检查读写权限,就很难发现这类错误。

同时,如下代码,通过栈(向下生长)中变量的地址,不断打印出朝高地址方向的地址,直接暴露出函数的调用栈。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值