刚接触 go,了解到切换协程仅需保存 3 个寄存器,那么剩余的怎么办呢,比如 ecx, eax 等

讨论 未结 7 55
jdz
jdz 会员 2022年7月9日 05:56 发表
<p>go 只保存了,pc ,sp 和 dx</p>
收藏(0)  分享
相关标签: 灌水交流
注意:本文归作者所有,未经作者允许,不得转载
7个回复
  • jdz
    jdz 会员 (楼主)
    2022年7月9日 06:28
    是因为 go 与 java 一样都是基于栈的虚拟机?
    0 0
  • qbqbqbqb
    2022年7月9日 06:56
    应该是和 go 的调用约定有关,只保存被调用者保存( callee-saved )的寄存器,调用者保存( caller-saved )的寄存器是由函数本身生成的代码自己负责的。 因为协程不是像线程那样由 OS 强行抢占的,是只有在特定的切换点才能切换,可以把这个切换的过程理解成一个特殊的函数调用 [而且 go 里面就有这么一个函数 runtime.Gosched()] 。caller-saved 寄存器如果需要保存的话,编译器会生成相应的代码,不用协程调度器保存。
    0 0
  • dearmymy
    2022年7月9日 07:27
    这个跟 go 无关把。你协程本来也应该在函数内,其他寄存器在进入函数前都 pushall 了,只要协程能找回栈信息就能恢复把。
    0 0
  • GeruzoniAnsasu
    2022年7月9日 08:57
    我有个印象,可能记错别太当真,就是,golang 会把函数内所有变量和参数都复制到栈上,所以可能只要 sp 指回来整个栈帧就能恢复
    0 0
  • iceheart
    2022年7月9日 09:56
    分版本,go1.15 之前用栈传参,go1.16 之后用寄存器传参了
    0 0
  • stach
    2022年7月9日 10:57
    我认为:剩余的寄存器,比如 ecx ,eax 等,协程切换时,保存在 go 的栈上。(不管是老的,还是新的调用规约)
    0 0
  • jobmailcn
    2022年7月9日 11:57
    eax ebx ecx edx 这些数据寄存器本来就不会跨函数吧,所以这几个是不需要保存的,不然每次函数调用也需要保存,代价太高。
    0 0