Skip to content

高版本的Go编译器,为什么在使用原生go代码是使用寄存器传参,但是在汇编实现中却使用栈传参?有可能改变这种行为吗? #647

Open
@qshuai

Description

@qshuai

Go version:

go version go1.22.1 linux/amd64
  • 使用go代码实现:
package main

//go:noinline
func add(a, b uint64) uint64 {
	return a + b
}

func main() {
	_ = add(2, 3)
}

指令:使用了寄存器传参(命令: go build add_native.gogo tool objdump -s '^main.' add_native):

TEXT main.add(SB) /root/project/go/src/github.com/qshuai/test/asm/add_native.go
  add_native.go:5	0x45d140		4801d8			ADDQ BX, AX     // 使用寄存器处理参数和返回值
  add_native.go:5	0x45d143		c3			RET

TEXT main.main(SB) /root/project/go/src/github.com/qshuai/test/asm/add_native.go
  add_native.go:8	0x45d160		493b6610		CMPQ SP, 0x10(R14)
  add_native.go:8	0x45d164		761d			JBE 0x45d183
  add_native.go:8	0x45d166		55			PUSHQ BP
  add_native.go:8	0x45d167		4889e5			MOVQ SP, BP
  add_native.go:8	0x45d16a		4883ec10		SUBQ $0x10, SP
  add_native.go:9	0x45d16e		b802000000		MOVL $0x2, AX
  add_native.go:9	0x45d173		bb03000000		MOVL $0x3, BX
  add_native.go:9	0x45d178		e8c3ffffff		CALL main.add(SB)
  add_native.go:10	0x45d17d		4883c410		ADDQ $0x10, SP
  add_native.go:10	0x45d181		5d			POPQ BP
  add_native.go:10	0x45d182		c3			RET
  add_native.go:8	0x45d183		e898cdffff		CALL runtime.morestack_noctxt.abi0(SB)
  add_native.go:8	0x45d188		ebd6			JMP main.main(SB)
  • 使用汇编实现add函数
// go code
package main

//go:noinline
func add(a, b uint64) uint64

func main() {
	_ = add(2, 3)
}

// asm
TEXT ·add(SB), $0-0
  ADDQ BX, AX
  RET

指令:使用栈传参(命令:go buildgo tool objdump -s '^main.' xxx):

TEXT main.main(SB) /root/project/go/src/github.com/qshuai/test/asm/add.go
  add.go:6		0x45d140		493b6610		CMPQ SP, 0x10(R14)
  add.go:6		0x45d144		7632			JBE 0x45d178
  add.go:6		0x45d146		55			PUSHQ BP
  add.go:6		0x45d147		4889e5			MOVQ SP, BP
  add.go:6		0x45d14a		4883ec18		SUBQ $0x18, SP
  add.go:7		0x45d14e		48c7042402000000	MOVQ $0x2, 0(SP)    // 使用栈传参:2
  add.go:7		0x45d156		48c744240803000000	MOVQ $0x3, 0x8(SP)  // 使用栈传参:3
  add.go:7		0x45d15f		90			NOPL
  add.go:7		0x45d160		e81b000000		CALL main.add.abi0(SB)
  add.go:7		0x45d165		450f57ff		XORPS X15, X15
  add.go:7		0x45d169		644c8b3425f8ffffff	MOVQ FS:0xfffffff8, R14
  add.go:8		0x45d172		4883c418		ADDQ $0x18, SP
  add.go:8		0x45d176		5d			POPQ BP
  add.go:8		0x45d177		c3			RET
  add.go:6		0x45d178		e8a3cdffff		CALL runtime.morestack_noctxt.abi0(SB)
  add.go:6		0x45d17d		ebc1			JMP main.main(SB)

TEXT main.add.abi0(SB) /root/project/go/src/github.com/qshuai/test/asm/add_amd64.s
  add_amd64.s:2		0x45d180		4801d8			ADDQ BX, AX  // 这个逻辑就错误了
  add_amd64.s:3		0x45d183		c3			RET

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions