简体   繁体   English

使用程序集调用其他由程序集编写的自定义 function

[英]use assembly call other custom function written by assembly

I want to use go assembly implement below two functions我想使用 go 汇编器实现以下两个功能

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并在 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时,出现了一些难以调试的错误,我认为错误是调用Sum的方式错误,如果您有任何想法,请给出错误的建议,非常感谢!

$  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:我做了很多方法,最后,使用go tool compile -N -l -S main.go调试下面的代码以获得一些有用的信息:

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但是我还有一个疑问,为什么用MOVQ 16(SP), AX可以得到Sum的返回值,因为我觉得AA function栈是这样的

------
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如果 function 堆栈正确,它将与MOVQ 40(SP), AX一起使用,我对此感到非常困惑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM