I want to use go assembly implement below two functions
func AA(a, b int) {
var ret = sum(a, b)
println(ret)
}
func sum(a, b int) int {
return a+b
}
and use in main.go
func main() {
pkg.AA(1,2)
}
Below is my code:
pkg/pkg.go
func Sum(a,b int) int
func AA(a, b int)
pkg/pkg_amd64.s
TEXT ·AA(SB),NOSPLIT,$8-16
MOVQ arg1+0(FP), AX
MOVQ arg2+8(FP), BX
MOVQ AX, (SP)
MOVQ BX, +8(SP)
CALL ·Sum(SB)
RET
TEXT ·Sum(SB),NOSPLIT,$0
MOVQ arg1+0(FP), AX // AX = arg1
MOVQ arg2+8(FP), BX // BX = arg2
ADDQ AX, BX // BX += AX
MOVQ BX, ret1+16(FP)
RET
But when I execute go run main.go
, there have some errors that hardly to debug, I think the error is wrong way to call Sum, if you have any idea ,please give some advise for that error,thank a lot!
$ go run main.go
runtime: unexpected return pc for runtime.sigpanic called from 0x1
stack: frame={sp:0xc000056720, fp:0xc000056758} stack=[0xc000056000,0xc000056800)
000000c000056620: 0000000000000000 000000c0000566f0
000000c000056630: 000000000102ca65 <runtime.gopanic+293> 000000c000000180
000000c000056640: 000000000102b0fb <runtime.panicmem+91> 000000c000056700
000000c000056650: 0000000000000000 0000000000000055
000000c000056660: 000000000113a9f0 00000000010cb720
000000c000056670: 000000c0000566a8 000000000100aaea <runtime.(*mcache).nextFree+170>
000000c000056680: 000000000113a9f0 000000c000000180
000000c000056690: 0000000001004b85 <runtime.chanrecv+997> 000000c00006e000
000000c0000566a0: 000000000113a9f0 000000c000056730
000000c0000566b0: 000000c0000001a0 0000000000000000
000000c0000566c0: 0000000001067c40 00000000010c93b0
000000c0000566d0: 0000000000000000 0000000000000000
000000c0000566e0: 0000000000000000 0000000000000000
000000c0000566f0: 000000c000056710 000000000102b0fb <runtime.panicmem+91>
000000c000056700: 0000000001067c40 00000000010c93b0
000000c000056710: 000000c000056748 0000000001041dd9 <runtime.sigpanic+377>
000000c000056720: <00000000010cb720 0000000000000000
000000c000056730: 000000c000056778 000000c000056778
000000c000056740: 000000c000000180 000000c000056758
000000c000056750: !0000000000000001 >0000000000000002
000000c000056760: 000000000105e2f3 <main.main+51> 000000000105e2f5 <main.main+53>
000000c000056770: 0000000000000002 000000c0000567d0
000000c000056780: 000000000102fad6 <runtime.main+598> 000000c00007a000
000000c000056790: 0000000000000000 000000c00007a000
000000c0000567a0: 0000000000000000 0100000000000000
000000c0000567b0: 0000000000000000 000000c000000180
000000c0000567c0: 000000c0000567ae 0000000001078b80
000000c0000567d0: 0000000000000000 000000000105b061 <runtime.goexit+1>
000000c0000567e0: 0000000000000000 0000000000000000
000000c0000567f0: 0000000000000000 0000000000000000
fatal error: unknown caller pc
runtime stack:
runtime.throw(0x1074e46, 0x11)
/usr/local/go/src/runtime/panic.go:1117 +0x72
runtime.gentraceback(0x102b0fb, 0xc000056700, 0x0, 0xc000000180, 0x0, 0x0, 0x7fffffff, 0x7ffeefbff3c0, 0x0, 0x0, ...)
/usr/local/go/src/runtime/traceback.go:261 +0x1a56
runtime.addOneOpenDeferFrame.func1()
/usr/local/go/src/runtime/panic.go:717 +0x91
runtime.systemstack(0x0)
/usr/local/go/src/runtime/asm_amd64.s:379 +0x66
runtime.mstart()
/usr/local/go/src/runtime/proc.go:1246
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:339 fp=0xc0000565f8 sp=0xc0000565f0 pc=0x10593e0
runtime.addOneOpenDeferFrame(0xc000000180, 0x102b0fb, 0xc000056700)
/usr/local/go/src/runtime/panic.go:716 +0x7b fp=0xc000056638 sp=0xc0000565f8 pc=0x102bedb
panic(0x1067c40, 0x10c93b0)
/usr/local/go/src/runtime/panic.go:925 +0x125 fp=0xc000056700 sp=0xc000056638 pc=0x102ca65
runtime.panicmem()
/usr/local/go/src/runtime/panic.go:212 +0x5b fp=0xc000056720 sp=0xc000056700 pc=0x102b0fb
runtime: unexpected return pc for runtime.sigpanic called from 0x1
stack: frame={sp:0xc000056720, fp:0xc000056758} stack=[0xc000056000,0xc000056800)
000000c000056620: 0000000000000000 000000c0000566f0
000000c000056630: 000000000102ca65 <runtime.gopanic+293> 000000c000000180
000000c000056640: 000000000102b0fb <runtime.panicmem+91> 000000c000056700
000000c000056650: 0000000000000000 0000000000000055
000000c000056660: 000000000113a9f0 00000000010cb720
000000c000056670: 000000c0000566a8 000000000100aaea <runtime.(*mcache).nextFree+170>
000000c000056680: 000000000113a9f0 000000c000000180
000000c000056690: 0000000001004b85 <runtime.chanrecv+997> 000000c00006e000
000000c0000566a0: 000000000113a9f0 000000c000056730
000000c0000566b0: 000000c0000001a0 0000000000000000
000000c0000566c0: 0000000001067c40 00000000010c93b0
000000c0000566d0: 0000000000000000 0000000000000000
000000c0000566e0: 0000000000000000 0000000000000000
000000c0000566f0: 000000c000056710 000000000102b0fb <runtime.panicmem+91>
000000c000056700: 0000000001067c40 00000000010c93b0
000000c000056710: 000000c000056748 0000000001041dd9 <runtime.sigpanic+377>
000000c000056720: <00000000010cb720 0000000000000000
000000c000056730: 000000c000056778 000000c000056778
000000c000056740: 000000c000000180 000000c000056758
000000c000056750: !0000000000000001 >0000000000000002
000000c000056760: 000000000105e2f3 <main.main+51> 000000000105e2f5 <main.main+53>
000000c000056770: 0000000000000002 000000c0000567d0
000000c000056780: 000000000102fad6 <runtime.main+598> 000000c00007a000
000000c000056790: 0000000000000000 000000c00007a000
000000c0000567a0: 0000000000000000 0100000000000000
000000c0000567b0: 0000000000000000 000000c000000180
000000c0000567c0: 000000c0000567ae 0000000001078b80
000000c0000567d0: 0000000000000000 000000000105b061 <runtime.goexit+1>
000000c0000567e0: 0000000000000000 0000000000000000
000000c0000567f0: 0000000000000000 0000000000000000
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:734 +0x179 fp=0xc000056758 sp=0xc000056720 pc=0x1041dd9
exit status 2
I do many methods and finally, and use the go tool compile -N -l -S main.go
to debug below code for some useful infomation:
func printsum(a, b int) int{
return sum1(a, b)
}
func sum1(a, b int) int {
return a+b
}
and I find a method can pass the funtion,
TEXT ·AA(SB),NOSPLIT,$40-24
MOVQ a+0(FP), AX
MOVQ b+8(FP), BX
MOVQ AX, 0(SP) // need to put AX(arg1) in 0(SP), when call Sum, it will be used as the first param
MOVQ BX, 0x8(SP) // need to place BX(arg1) in 8(SP), when call Sum, it will be used as secnod param
CALL ·Sum(SB)
MOVQ 16(SP), AX
MOVQ AX,ret1+16(FP)
RET
TEXT ·Sum(SB),NOSPLIT,$0-24
MOVQ arg1+0(FP), AX // AX = arg1
MOVQ arg2+8(FP), BX // BX = arg2
ADDQ AX, BX // BX += AX
MOVQ BX, ret1+16(FP)
// MOVQ AX, (SP)
// CALL ·print(SB)
RET
But i still have a question, why use MOVQ 16(SP), AX
can get the return value that from Sum, because i think the AA
function stack is like this
------
ret0 (8 bytes)
------
arg1 (8 bytes)
------
arg0 (8 bytes)
------ FP
ret addr (8 bytes)
------
caller BP (8 bytes)
------ pseudo SP
frame content (8 bytes)
------ hardware SP
and if the function stack is correct, it will work with MOVQ 40(SP), AX
, I'm very confusing about it
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.