cch123 / blog_comment

comments of xargin.com
8 stars 0 forks source link

Plan9 汇编解析 | Go 语言笔记 #235

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

Plan9 汇编解析 | Go 语言笔记

Plan9 汇编解析 # 众所周知,Go 使用了 Unix 老古董(误 们发明的 plan9 汇编。就算你对 x86 汇编有所了解,在 plan9 里还是有些许区别。说不定你在看代码的时候,偶然发现代码里的 SP 看起来是 SP,但它实际上不是 SP 的时候就抓狂了哈哈哈。 本文将对 plan9 汇编进行全面的介绍,同时解答

https://go.xargin.com/docs/assembly/assembly/

kekemuyu commented 3 years ago

从汇编中可以看到有些指令或者寄存器简直就是为了c语言或者操作系统而生的,从这一点得出软件的发展又反向影响了硬件。

cch123 commented 3 years ago

从汇编中可以看到有些指令或者寄存器简直就是为了c语言或者操作系统而生的,从这一点得出软件的发展又反向影响了硬件。

硬件和 os 厂商本身是有合作的,功能设计上也要考虑软件商的需求

eddycjy commented 2 years ago

一只煎鱼成功抢占了板凳 (doge

nengqi commented 2 years ago

有个想法,图中栈空间布局图,像BP,SP这种,画在分界线位置有点模糊,最好指向某格的中间, 另外 BP和pseudo SP感觉不能放一起,*rbp 里面是caller rbp地址,而 这里的BP就指向local var 0,两者不是差了一格么

cch123 commented 2 years ago

有个想法,图中栈空间布局图,像BP,SP这种,画在分界线位置有点模糊,最好指向某格的中间, 另外 BP和pseudo SP感觉不能放一起,*rbp 里面是caller rbp地址,而 这里的BP就指向local var 0,两者不是差了一格么

实际指向的应该就是分界线位置。。

pseudo sp 和 bp 会不会差一格是要看当前的 framesize 是不是 > 0 的,这些比较麻烦

omigia commented 2 years ago

看了这篇+参考资料里的3、5,大体是理解了; 但本文伪寄存器部分总感觉不得劲,我就想补充点自己的理解。

1. 先提一点对本文部分说法的疑义

官方文档中说的伪 SP 指向 stack 的 top:原文(此处指本文参考5)是 the highest address within the local stack frame,本地栈帧的最高地址,这句应该没有问题,后面会补充。

2. 栈帧结构

2.1 执行过程及栈帧

参考 csapp->3.7.1节 运行时栈->图3-25 通用的栈帧结构

caller 调用 callee 涉及到的栈帧情况。 (栈的分配是从高地址向低地址分配) (下面SP指其他地方常见到的栈顶针寄存器,不同于伪SP)

  1. caller - SP-sizeof(callee返回值+参数)【1】,并对对应参数位置赋值;
  2. caller - 返回地址【2】入栈,SP减少;
  3. caller - 保存caller相关寄存器【3】,SP减少(caller BP?);
  4. caller - 调用callee,PC指向callee的代码段;
  5. callee - 分配本地变量+为调用其他func分配返回值、参数的栈帧【4】,SP减少;
  6. callee - 处理完毕,ret执行,将【2】中内容赋值给PC,更新SP为【1】的低地址;
  7. caller- 执行原本call callee之后的下一条指令。

2.2 根据前述解释伪寄存器

至此也能理解为什么伪 SP 寄存器能去找那些用 FP + offset 引用的值 -> 其本质都是地址相对引用;又为什么不该用 -> 不能保证两者间栈帧的大小。

cch123 commented 2 years ago

看了这篇+参考资料里的3、5,大体是理解了; 但本文伪寄存器部分总感觉不得劲,我就想补充点自己的理解。

1. 先提一点对本文部分说法的疑义

官方文档中说的伪 SP 指向 stack 的 top:原文(此处指本文参考5)是 the highest address within the local stack frame,本地栈帧的最高地址,这句应该没有问题,后面会补充。

2. 栈帧结构

2.1 执行过程及栈帧

参考 csapp->3.7.1节 运行时栈->图3-25 通用的栈帧结构

caller 调用 callee 涉及到的栈帧情况。 (栈的分配是从高地址向低地址分配) (下面SP指其他地方常见到的栈顶针寄存器,不同于伪SP)

  1. caller - SP-sizeof(callee返回值+参数)【1】,并对对应参数位置赋值;
  2. caller - 返回地址【2】入栈,SP减少;
  3. caller - 保存caller相关寄存器【3】,SP减少(caller BP?);
  4. caller - 调用callee,PC指向callee的代码段;
  5. callee - 分配本地变量+为调用其他func分配返回值、参数的栈帧【4】,SP减少;
  6. callee - 处理完毕,ret执行,将【2】中内容赋值给PC,更新SP为【1】的低地址;
  7. caller- 执行原本call callee之后的下一条指令。

2.2 根据前述解释伪寄存器

  • FP: 指向【1】的最低地址,symbol+offset(FP),0≤offset<sizeof(【1】);
  • (伪)SP:【4】的最高地址(也是【3】的最低地址),symbol-offset(SP),0<offset≤sizeof(【4】);回应前面的疑义,【4】就是本地栈帧;
  • SP:始终指向栈顶位置;当本func没有额外增加本地变量或调用其他func时,同(伪)SP。

至此也能理解为什么伪 SP 寄存器能去找那些用 FP + offset 引用的值 -> 其本质都是地址相对引用;又为什么不该用 -> 不能保证两者间栈帧的大小。

后面我给官方提过一次pr改这个文档,不过没修改全,arm的员工接力过去已经把sp的描述修改过了

cuishuang commented 2 years ago

或其--->获取