今天在翻閱Golang代碼時,發現了Golang調用匯編代碼的方法(詳見pkg/bytes)。大概要做三件事,我以用匯編實現一個判斷字符串是否相等的方法Equal為例,測試一下:
准備工作,創建工程目錄:
- asm_demo
- |--bin
- |--pkg
- |--src
- | |--strlib
- | |--demo
第一、編寫平台對應的編碼代碼。
匯給代碼文件以如下格式的命名:asm_$ARCH.s (asm_386.s,asm_amd64.s,asm_arm.s,...),我的環境是Ubuntu 12.04 LTS amd64架構.
- $ GOPATH=<youpath>/asm_demo
- $ cd $GOPATH
- $ cat <<EOF > src/strlib/asm_amd64.s
- TEXT .Equal(SB),7,$0
- MOVL len+8(FP),BX
- MOVL len1+24(FP),CX
- MOVL $0,AX
- CMPL BX,CX
- JNE eqret
- MOVQ p+0(FP),SI
- MOVQ q+16(FP),DI
- CLD
- REP; CMPSB
- MOVL $1,DX
- CMOVLEQ DX,AX
- eqret:
- MOVB AX,ret+32(FP)
- RET
- EOF
本段代碼來自 $GOROOT/src/pkg/bytes/asm_amd64.s
可以看出,其中的語法大致和Linux匯編一致,只是寄存器表示不相同,是來自plan9的語法嗎?哪個同鞋可以科普一下?
第二件事,就是讓用Go語言封裝一下這個API,讓編譯器可以識別:
- $ cat <<EOF > src/strlib/equal.go
- package strlib
- func Equal(a[]byte,b[]byte) bool
- EOF
最后一件事,使用之:
- $ cat <<EOF > src/demo/main.go
- package main
- import "strlib"
- func main() {
- e := strlib.Equal([]byte("hello"),[]byte("hello"))
- println(e)
- e := strlib.Equal([]byte("hessssllo"),[]byte("hello"))
- println(e)
- }
- EOF
執行看看效果:
- $ go run src/demo/main.go
- true
- false
調用成功,使用起來非常簡單,也很易讀。