是否可以在Google Go代碼中包含內聯彙編?是否可以在Google Go代碼中包含內聯彙編?
回答
不支持內聯彙編,但是您可以使用匯編編寫的代碼通過C鏈接,使用cgo編譯並使用import "C"
,如gmp.go。您也可以使用與Go直接兼容的裝配樣式編寫代碼,如asm_linux_amd64.s,它要求函數名稱以「·」開頭。或者,您可以使用nasm和gccgo,這是我目前爲止最喜歡的方式。 (請注意,Nasm似乎不支持以「·」開頭的函數)。
這裏有一個工作的 「Hello World」 的例子:
hello.asm:
; Based on hello.asm from nasm
SECTION .data ; data section
msg: db "Hello World",10 ; the string to print, 10=cr
len: equ $-msg ; "$" means "here"
; len is a value, not an address
SECTION .text ; code section
global go.main.hello ; make label available to linker (Go)
go.main.hello:
; --- setup stack frame
push rbp ; save old base pointer
mov rbp,rsp ; use stack pointer as new base pointer
; --- print message
mov edx,len ; arg3, length of string to print
mov ecx,msg ; arg2, pointer to string
mov ebx,1 ; arg1, where to write, screen
mov eax,4 ; write sysout command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
; --- takedown stack frame
mov rsp,rbp ; use base pointer as new stack pointer
pop rbp ; get the old base pointer
; --- return
mov rax,0 ; error code 0, normal, no error
ret ; return
main.go:
package main
func hello();
func main() {
hello()
hello()
}
和方便的Makefile:
main: main.go hello.o
gccgo hello.o main.go -o main
hello.o: hello.asm
nasm -f elf64 -o hello.o hello.asm
clean:
rm -rf _obj *.o *~ *.6 *.gch a.out main
我致電hello()
在main.go中兩次,只是爲了再次檢查hello()是否正確返回。
請注意,調用中斷80H直接不被認爲是在Linux上良好的作風,並要求寫的函數是C更「面向未來」。還要注意,這是針對64位Linux的程序集,並且不以任何方式,形狀或形式與平臺無關。
我知道這是不是直接回答你的問題,但它是使用裝配有圍棋,在缺乏內聯的,我知道最簡單的途徑。如果您真的需要內聯,可以編寫一個腳本從源文件中提取內聯彙編,並按照上述模式進行準備。足夠近? :)
用於圍棋,C和NASM簡單的例子:gonasm.tgz
更新:gccgo的更高版本需要-g標誌,只有 「main.hello」 需要,而不是「go.main.hello 」。這裏是Go,C和Yasm的更新示例:goyasm.tgz
有在轉到編程語言,支持在線彙編語言代碼沒有設施,並且沒有計劃這樣做。 Go支持鏈接到在assembler和C中編寫的例程。有一個實驗性功能,將SWIG support添加到Go中。
標準Go編譯器(即:8g + 8l,而不是gccgo)中的優化傳遞基本上使用二進制形式的原始指令。目前,編譯器無法(未實現)將編譯器生成的程序集與用戶提供的內聯彙編代碼區分開來 - 此是Go編譯器不允許內聯彙編的主要原因。換句話說,由於編譯器體系結構,編譯器不支持內聯彙編。
還有就是在Go語言本身,這將阻止其他圍棋語言的實現當然不是什麼(即:其他圍棋編譯器),以有內聯彙編的支持。內聯彙編是一個編譯器特定的決定 - 它與Go語言本身無關。
在這兩種情況下,內聯彙編都是不安全的,因爲它的Go類型系統無法檢查其正確性。看起來最好是實現任何需要使用C語言內聯彙編的函數,並從Go中調用C函數。
最好不要使用內聯asm,原始版本的C和Unix不需要它或實現它,它使代碼變得不可移植並且 – uriel 2012-06-15 12:01:28
事實證明這是可能的,請參閱:http://www.doxsey.net/blog/go-and-assembly。
這就是不是*內聯*彙編,但。 – Alexander 2013-11-10 11:44:32
不,您不能,但通過使用go編譯器很容易提供一個函數的彙編實現。沒有必要使用「導入C」來使用匯編。
看看一個例子來自數學庫:
http://golang.org/src/pkg/math/abs.go:ABS功能在這一點去文件中聲明。 (也有在往這個文件的ABS的實現,但這不出口,因爲它有一個小寫的名字。)
package math
// Abs returns the absolute value of x.
//
// Special cases are:
// Abs(±Inf) = +Inf
// Abs(NaN) = NaN
func Abs(x float64) float64
然後,在http://golang.org/src/pkg/math/abs_amd64.s,ABS是在英特爾的64位執行本文件:
// func Abs(x float64) float64
TEXT ·Abs(SB),NOSPLIT,$0
MOVQ $(1<<63), BX
MOVQ BX, X0 // movsd $(-0.0), x0
MOVSD x+0(FP), X1
ANDNPD X1, X0
MOVSD X0, ret+8(FP)
RET
- 1. 是否可以將彙編代碼包含到php腳本中?
- 2. %c在GCC內聯彙編代碼中的含義是什麼?
- 3. GCC彙編內聯:與只有內聯彙編代碼
- 4. 是否可以包含內存中的PHP代碼?
- 5. 是否有可能強制內聯彙編代碼中的特定寄存器?
- 6. 替換內聯彙編代碼
- 7. 用C++替換內聯彙編代碼
- 8. 一個strcpy gcc內聯彙編代碼
- 9. substring - c內聯彙編代碼
- 10. GCC C++和內聯彙編代碼?
- 11. JIT內聯可以將我的代碼內聯到一些.NET運行時彙編代碼中嗎?
- 12. 內聯彙編代碼無法在Visual C++ 2010 Express中編譯
- 13. 內聯元素是否可以包含塊元素?
- 14. 彙編代碼在gdb中的含義
- 15. GCC內聯彙編可變
- 16. 含義的彙編代碼
- 17. 一個包含C代碼和彙編代碼的C項目
- 18. 編譯彙編代碼,其中包括含C-定義
- 19. 在OpenGL程序中是否可以包含Google Earth圖像?
- 20. 是否可以在IFrame中包含DocuSign
- 21. 是否可以在「if()」中包含=號?
- 22. 如何在C++內聯彙編代碼中使用字符串?
- 23. 是否有反彙編程序生成可編譯的彙編源代碼?
- 24. 哪個內聯彙編代碼對於rdtscp是正確的?
- 25. 彙編代碼是否跨平臺?
- 26. 這段彙編代碼是否無效?
- 27. Inline PTX彙編代碼是否強大?
- 28. base64編碼的字符串是否可以包含空格?
- 29. 是否可以顯示包含的源代碼
- 30. 是否可以包含/將代碼導入Android Manifest?
+1的鏈接的引用使得這個完美的答案;) – OscarRyz 2010-06-01 16:15:34
@OscarReyes:完成 – peterSO 2010-06-01 16:43:47
+1現在,它是完美的! :) – OscarRyz 2010-06-01 17:00:36