4

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

 2 years ago
source link: https://www.v2ex.com/t/865099
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Go 编程语言

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

  jdz · 6 小时 6 分钟前 via Android · 1057 次点击

go 只保存了,pc ,sp 和 dx

7 条回复    2022-07-09 19:40:30 +08:00
jdz

jdz      5 小时 51 分钟前 via Android

是因为 go 与 java 一样都是基于栈的虚拟机?
qbqbqbqb

qbqbqbqb      5 小时 0 分钟前

应该是和 go 的调用约定有关,只保存被调用者保存( callee-saved )的寄存器,调用者保存( caller-saved )的寄存器是由函数本身生成的代码自己负责的。

因为协程不是像线程那样由 OS 强行抢占的,是只有在特定的切换点才能切换,可以把这个切换的过程理解成一个特殊的函数调用 [而且 go 里面就有这么一个函数 runtime.Gosched()] 。caller-saved 寄存器如果需要保存的话,编译器会生成相应的代码,不用协程调度器保存。
dearmymy

dearmymy      4 小时 42 分钟前

这个跟 go 无关把。你协程本来也应该在函数内,其他寄存器在进入函数前都 pushall 了,只要协程能找回栈信息就能恢复把。
GeruzoniAnsasu

GeruzoniAnsasu      3 小时 10 分钟前

我有个印象,可能记错别太当真,就是,golang 会把函数内所有变量和参数都复制到栈上,所以可能只要 sp 指回来整个栈帧就能恢复
iceheart

iceheart      2 小时 2 分钟前 via Android   ❤️ 1

分版本,go1.15 之前用栈传参,go1.16 之后用寄存器传参了
stach

stach      1 小时 9 分钟前

我认为:剩余的寄存器,比如 ecx ,eax 等,协程切换时,保存在 go 的栈上。(不管是老的,还是新的调用规约)
jobmailcn

jobmailcn      12 分钟前 via Android

eax ebx ecx edx 这些数据寄存器本来就不会跨函数吧,所以这几个是不需要保存的,不然每次函数调用也需要保存,代价太高。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK