Go Assembly by Example: Hello
The following example is a bad example. It was obtained by using the following command on a simple Go program printing the string “hello world”:
go tool compile -S helloworld.go
package main
//The underscore _ is to avoid an “unusued package” compiler error.
import _ "fmt"
func hello()
func main() {
hello()
}
This #include
is needed to use Go Assembly’s constants (for example the RODATA
that we use later on). Other pre-processor macros can be used in Go Assembly (like #define
).
#include "textflag.h"
DATA allows you to store global words in memory 1, 2, 4 or 8 bytes at a time. The <>
after the symbol name restricts the data to the current file.
DATA world<>+0(SB)/8, $"hello wo"
DATA world<>+8(SB)/4, $"rld "
//GLOBL makes the data global and read-only (RODATA) for the relevant length (12).
GLOBL world<>+0(SB), RODATA, $12
TEXT ·hello(SB),$88-0
SUBQ $88, SP
MOVQ BP, 80(SP)
LEAQ 80(SP), BP
//A Go string is created in my_string (a pointer to the string followed by the string’s length).
LEAQ world<>+0(SB), AX
MOVQ AX, my_string+48(SP)
MOVQ $11, my_string+56(SP)
MOVQ $0, autotmp_0+64(SP)
MOVQ $0, autotmp_0+72(SP)
LEAQ type·string(SB), AX
MOVQ AX, (SP)
LEAQ my_string+48(SP), AX
MOVQ AX, 8(SP)
//convT2E from the runtime package is used to create an interface.
CALL runtime·convT2E(SB)
MOVQ 24(SP), AX
MOVQ 16(SP), CX
MOVQ CX, autotmp_0+64(SP)
MOVQ AX, autotmp_0+72(SP)
LEAQ autotmp_0+64(SP), AX
MOVQ AX, (SP)
MOVQ $1, 8(SP)
MOVQ $1, 16(SP)
//fmt.Println is called with the interface created
CALL fmt·Println(SB)
//This is pretty complicated, the lesson here is: don’t try to call functions from Go’s assembly.
MOVQ 80(SP), BP
ADDQ $88, SP
RET
Next example: Arcsin.
ft_authoradmin ft_create_time2018-02-03 13:02
ft_update_time2018-02-03 13:04
ft_update_time2018-02-03 13:04