Golang调用汇编代码

今天在翻阅Golang代码时,发现了Golang调用汇编代码的方法(详见pkg/bytes)。大概要做三件事,我以用汇编实现一个判断字符串是否相等的方法Equal为例,测试一下:

准备工作,创建工程目录:

  1. asm_demo
  2. |--bin
  3. |--pkg
  4. |--src
  5. | |--strlib
  6. | |--demo

第一、编写平台对应的编码代码。

汇给代码文件以如下格式的命名:asm_$ARCH.s (asm_386.s,asm_amd64.s,asm_arm.s,...),我的环境是Ubuntu 12.04 LTS amd64架构.

  1. $ GOPATH=<youpath>/asm_demo
  2. $ cd $GOPATH
  3. $ cat <<EOF > src/strlib/asm_amd64.s
  4. TEXT .Equal(SB),7,$0
  5. MOVL len+8(FP),BX
  6. MOVL len1+24(FP),CX
  7. MOVL $0,AX
  8. CMPL BX,CX
  9. JNE eqret
  10. MOVQ p+0(FP),SI
  11. MOVQ q+16(FP),DI
  12. CLD
  13. REP; CMPSB
  14. MOVL $1,DX
  15. CMOVLEQ DX,AX
  16. eqret:
  17. MOVB AX,ret+32(FP)
  18. RET
  19. EOF

本段代码来自 $GOROOT/src/pkg/bytes/asm_amd64.s
可以看出,其中的语法大致和Linux汇编一致,只是寄存器表示不相同,是来自plan9的语法吗?哪个同鞋可以科普一下?

第二件事,就是让用Go语言封装一下这个API,让编译器可以识别:

  1. $ cat <<EOF > src/strlib/equal.go
  2. package strlib
  3.  
  4. func Equal(a[]byte,b[]byte) bool
  5.  
  6. EOF

最后一件事,使用之:

  1. $ cat <<EOF > src/demo/main.go
  2. package main
  3.  
  4. import "strlib"
  5.  
  6. func main() {
  7. e := strlib.Equal([]byte("hello"),[]byte("hello"))
  8. println(e)
  9.  
  10. e := strlib.Equal([]byte("hessssllo"),[]byte("hello"))
  11. println(e)
  12. }
  13. EOF


执行看看效果:

  1. $ go run src/demo/main.go
  2. true
  3. false

调用成功,使用起来非常简单,也很易读。

原文地址:https://www.cnblogs.com/dream397/p/14270604.html