cch123 / blog_comment

comments of xargin.com
8 stars 0 forks source link

Go 系列文章3 :plan9 汇编入门 #37

Open cch123 opened 6 years ago

cch123 commented 6 years ago

http://xargin.com/plan9-assembly/

cnbailian commented 3 years ago

曹大你好,本篇文章在“栈调整”中写了“intel 或 AT&T 汇编提供了 push 和 pop 指令族,plan9 中没有 push 和 pop” 可是在之前的《[译]go 和 plan9 汇编》文章中说了“Go 编译器不会生成任何 PUSH/POP 族的指令: 栈的增长和收缩是通过在栈指针寄存器 SP 上分别执行减法和加法指令来实现的” 并且在我实际的测试中确实是有 PUSH 和 POP 指令的,所以这里的表述是否不太准确

cch123 commented 3 years ago

@cnbailian 曹大你好,本篇文章在“栈调整”中写了“intel 或 AT&T 汇编提供了 push 和 pop 指令族,plan9 中没有 push 和 pop” 可是在之前的《[译]go 和 plan9 汇编》文章中说了“Go 编译器不会生成任何 PUSH/POP 族的指令: 栈的增长和收缩是通过在栈指针寄存器 SP 上分别执行减法和加法指令来实现的” 并且在我实际的测试中确实是有 PUSH 和 POP 指令的,所以这里的表述是否不太准确

我好像确实没见过 push 和 pop。。啥样的代码会有呢,求 demo

cnbailian commented 3 years ago

比如说这里:https://github.com/golang/go/blob/master/src/runtime/asm_amd64.s#L220

虽然 Go 编译器生成的函数不会用 PUSH 和 POP,但 plan9 的语法里确实是有的,自己写的 plan9 汇编也可以用。Go 好像不是很喜欢用这个指令,在源码里也很少见。

我在初读这篇文章时根据文章的表述误认为了 plan9 没有 PUSH 和 POP 指令,后来发现是有的,所以我觉得这里的表述有一定误导。

AlanWZHU commented 3 years ago
ADDQ $0x18, SP // 对 SP 做加法,清除函数栈帧

加法是清除函数栈帧 是因为 栈 地址是由高到低么

cch123 commented 3 years ago

@AlanWZHU

ADDQ $0x18, SP // 对 SP 做加法,清除函数栈帧

加法是清除函数栈帧 是因为 栈 地址是由高到低么

是的

cch123 commented 3 years ago

比如说这里:https://github.com/golang/go/blob/master/src/runtime/asm_amd64.s#L220

虽然 Go 编译器生成的函数不会用 PUSH 和 POP,但 plan9 的语法里确实是有的,自己写的 plan9 汇编也可以用。Go 好像不是很喜欢用这个指令,在源码里也很少见。

我在初读这篇文章时根据文章的表述误认为了 plan9 没有 PUSH 和 POP 指令,后来发现是有的,所以我觉得这里的表述有一定误导。

感谢指正,我先把那行划掉了

watermeion commented 2 years ago
// func add(a, b int) int
//   => 该声明定义在同一个 package 下的任意 .go 文件中
//   => 只有函数头,没有实现
TEXT pkgname·add(SB), NOSPLIT, $0-8
    MOVQ a+0(FP), AX
    MOVQ a+8(FP), BX
    ADDQ AX, BX
    MOVQ BX, ret+16(FP)
    RET

想请教下,文中这个例子里, MOVQ a+8(FP), BX ,应该是 MOVQ b+8(FP), BX 吧?

h4rv9y commented 2 years ago

曹大你好,我在自己测试的时候发现编译器生成出来的 4 字节后缀指令不是 MOVD 而是 MOVL。我在搜索 Go 标准库中的源码发现,这两个指令都有使用。其中 MOVD 在 s390x 和 arm64 汇编中出现,而 MOVL 则出现在 x86 汇编中。想请教下这两个指令的区别。

cch123 commented 2 years ago
// func add(a, b int) int
//   => 该声明定义在同一个 package 下的任意 .go 文件中
//   => 只有函数头,没有实现
TEXT pkgname·add(SB), NOSPLIT, $0-8
    MOVQ a+0(FP), AX
    MOVQ a+8(FP), BX
    ADDQ AX, BX
    MOVQ BX, ret+16(FP)
    RET

想请教下,文中这个例子里, MOVQ a+8(FP), BX ,应该是 MOVQ b+8(FP), BX 吧?

不同版本会有差别

cch123 commented 2 years ago

曹大你好,我在自己测试的时候发现编译器生成出来的 4 字节后缀指令不是 MOVD 而是 MOVL。我在搜索 Go 标准库中的源码发现,这两个指令都有使用。其中 MOVD 在 s390x 和 arm64 汇编中出现,而 MOVL 则出现在 x86 汇编中。想请教下这两个指令的区别。

plan9的指令说到底还是个中间指令,要看最终被翻译到硬件平台是什么,可以在dlv里用disass来看,这些至少可以找cpu的官方manual来查