Is it possible to include inline assembly in Go code?
5条回答 默认 最新
- doumenshi1475 2011-06-30 13:36关注
There is no support for inline assembly, but you can link with code written in assembly through C, compiling with cgo and using
import "C"
, like in gmp.go. You could alternatively write in a style of assembly that is directly compatible with Go, like in asm_linux_amd64.s, that requires that function names start with "·".Or, you can use nasm and gccgo, my favorite way so far. (Note that Nasm does not seem to support functions starting with "·").
Here's a working "hello world" example:
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() }
And a handy 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
I call
hello()
twice in main.go, just to double check that hello() returns properly.Note that calling interrupt 80h directly is not considered good style on Linux, and calling functions written is C is more "future proof". Also note that this is assembly specifically for 64-bit Linux, and is not platform-independent in any way, shape or form.
I know it's not a direct answer to your question, but it's the easiest route I know for using assembly with Go, in lack of inlining. If you really need inlining, it's possible to write a script that extracts inline assembly from source files and prepares it in a way that follows the pattern above. Close enough? :)
Quick example for Go, C and Nasm: gonasm.tgz
Update: Later versions of gccgo needs the -g flag and only "main.hello" is needed instead of "go.main.hello". Here is an updated example for Go, C and Yasm: goyasm.tgz
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 多电路系统共用电源的串扰问题
- ¥15 shape_predictor_68_face_landmarks.dat
- ¥15 slam rangenet++配置
- ¥15 有没有研究水声通信方面的帮我改俩matlab代码
- ¥15 对于相关问题的求解与代码
- ¥15 ubuntu子系统密码忘记
- ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
- ¥15 保护模式-系统加载-段寄存器
- ¥15 电脑桌面设定一个区域禁止鼠标操作
- ¥15 求NPF226060磁芯的详细资料