go编译器生成的汇编代码中的这种模式是什么?

我正在调试Linux内核中一个无关紧要的问题,看到由supervisor管理的etcd进程反复遇到页面错误异常并收到SIGSEGV。


我很好奇并使用 objdump 反汇编程序,发现错误的 amd64 指令是:


89 04 25 00 00 00 00    mov    %eax,0x0

然后我查看了一个 hello world 程序的反汇编。我在 go 编译器生成的代码中看到了一个很常见的模式,就是在一个函数的末尾,紧跟在 之后ret,mov然后是一个jmpback 到函数中。例如,


0000000000400c00 <main.main>:

  400c00:       64 48 8b 0c 25 f0 ff    mov    %fs:0xfffffffffffffff0,%rcx

  400c07:       ff ff

        ...

  400c4b:       48 83 7c 24 48 00       cmpq   $0x0,0x48(%rsp)

  400c51:       74 59                   je     400cac <main.main+0xac>

  400c53:       48 c7 04 24 c0 fc 47    movq   $0x47fcc0,(%rsp)

  400c5a:       00


        ...

  400cab:       c3                      retq

  400cac:       89 04 25 00 00 00 00    mov    %eax,0x0

  400cb3:       eb 9e                   jmp    400c53 <main.main+0x53>

这是 go 玩的什么把戏吗?如果是这样,它是如何工作的?我猜0x400c51它会跳转到0x400cac,触发 a SIGSEGV,它被处理,然后下一条指令跳回0x400c53.


潇湘沐
浏览 240回答 1
1回答

千万里不及你

我从 Go 开发人员那里得到了一些答案:https&nbsp;:&nbsp;//groups.google.com/forum/#!topic/&nbsp;golang-nuts/&nbsp;_7yio3ZfVBE基本上,这种模式是过时实现中的 nil 检查。引用的是 Keith Randall 的回答。如果指针为零,则跳转到产生错误的指令。该错误用于启动 nil ptr panic。这是一个非常低效的代码序列。jmps 似乎从未被使用过。升级到更新的 Go 版本,您会看到它已得到改进。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go