This is a creation in Article, where the information may have evolved or changed. There are a lot of assembly statements in the Go source code, the best examples are in the ' Math/big ', ' Runtime ' and ' crypto ' libraries, but getting started here is too painful, and these examples are running code that focuses on system operations and performance. For inexperienced Go language enthusiasts, this can make learning through library code a lot harder. This is why this article was written. Go ASM (Translator Note: ASM is shorthand for compilation) is a special form of assembly language used by the Go compiler, and it is based on Plan 9 (translator note: concept from Bell Labs [network operating system] (Https://baike.baidu.com/item/%E7%B d%91%e7%bb%9c%e6%93%8d%e4%bd%9c%e7%b3%bb%e7%bb%9f)) Enter a style, so it's a good idea to start with [document] (https://9p.io/sys/doc/asm.pdf). Note: The content of this article is based on the x86_64 architecture, but most of the examples are compatible with the x86 architecture. Some examples are selected from the original document, and the main purpose is to create a comprehensive summary of the unified standard that covers the most important/useful topics. # # The first step go ASM and the standard assembler syntax (NASM or yasm) are not quite the same, first you will find that it is architecture independent, there is no so-called 32 or 64 bit registers, as shown in: | NASM x86 | NASM x64 | Go ASM | | -------- | -------- | ------ || EAX | Rax | AX | | EBX | RBX | BX | | ECX | RCX | CX | | ... | ... | ... | Most register symbols are dependent on the schema. In addition, Go ASM has four predefined symbols as pseudo-registers. They are not real registers, but virtual registers that are maintained by the toolchain, which are identical on all architectures:-' FP ': Frame pointers-parameters and local variables –-' PC ': Program counter – Jump and branch –-' SB ': Static base Address pointer – Global symbol –-' SP ': Stack pointer – Top of the stack – these virtual registers are important in Go ASM and are widely used, the most important of which is the SB and FP. The pseudo register SB can be considered as the starting address of the memory, so foo (SB) is the address of Foo in memory. There are two kinds of modifiers in the syntax, <&Gt and +n (N is an integer). In the first case, foo<> (SB) represents a private element that can be accessed only in the same source file, similar to the lowercase name in Go. The second is the address obtained after adding an offset to the relative address, so Foo+8 (SB) points to the address at 8 bytes after Foo. The pseudo register FP is a virtual frame pointer that is used to refer to the process parameters, which are maintained by the compiler and will point to the arguments in the stack that are offset from the pseudo register. On a 64-bit machine, 0 (FP) is the first parameter, and a 8 (FP) is the second parameter. To reference these parameters, the compiler enforces their naming, for clarity and readability. So MOVL foo+0 (FP), CX puts the first parameter in the virtual FP register into the physical CX register, and the MOVL bar+8 (FP), the DX puts the second parameter into the DX register. Readers may have noticed that this ASM syntax is similar to the T-style, but not exactly the same: | Intel | T | Go | | ------------------ | -------------------- | ------------------ || ' mov eax, 1 ' | ' Movl $,%eax ' | ' Movq $, AX ' | | ' mov rbx, 0ffh ' | ' Movl $0xff,%rbx ' | ' Movq $ (0xff), BX ' | | ' mov ecx, [ebx+3] ' | ' Movl 3 (%EBX),%ecx ' | ' Movq 2 (BX), CX ' | Another significant difference is the global source file structure, the code structure in NASM is clearly defined by the section: "' Asmglobal startsection. bss...section. data...section . Textstart:mov Rax, 0x2000001mov rdi, 0x00syscall "and in the Go assembly is a predefined section type symbol:" ' Asmdata myint<>+0x00 (SB)/8, $ 42GLOBL myint<> (SB), Rodata, $8//func foo () text foo (SB), Nosplit, $0movq $, Dxleaq myint≪> (SB), Dxret ' This syntax allows us to define the symbol in the most appropriate place possible. # # in Go Call assembly code can be found from the introduction, the assembly code in Go is mainly used to optimize and interact with the underlying system, which makes go ASM does not run independently like other classic assembly code. Go ASM must be called in the Go code. Hello.go ' Gopackage mainfunc neg (x UInt64) Int64func main () {println (neg)} ' hello_amd64.s ' ' asmtext neg (SB), Nosplit, $0movq x+0 (FP), Axnegq axmovq AX, Ret+8 (FP) ret ' ' Run this code will print out 42 on the terminal. Note The Unicode midpoint at the beginning of the sub-procedure symbol ' • ', which is delimited for the package name, without the prefix ' foo ' equivalent to ' main foo '. The process of ' text neg (SB), Nosplit, $ A ' means:-' text ': This symbol is located in ' Text ' section. -' neg ': The package symbols and symbols for the process. -' (SB) ': The lexical analyzer will use. -' nosplit ': makes it unnecessary to define the parameter size. – Omit to write –-' $ ': the size of the parameter, if the definition of ' nosplit ' is ' $ '. The build step is still the same as usual, using the ' Go Build ' command, the go compiler will follow the filename – ' amd64 ' – Automatically link '. s ' files. There is also a resource to help you learn the process of compiling the go file, and we can look at the ' Go tool build-s <file.go> ' generated go ASM. Some symbols like ' nosplit ' and ' rodata ' are defined in the ' Textflax ' header file, so using ' #include textflag.h ' to include the file can be useful for completing a perfect compilation without an error. # # # system calls in MacOS require a system call in MacOS to be called with the call number ' 0x2000000 ', for example, the exit system call is ' 0x2000001 '. The ' 2 ' at the beginning of the call is because there are multiple kinds of calls that are defined in the range of overlapping call numbers, which are defined in [here] (https://opensource.apple.com/source/xnu/xnu-792.10.96/osfmk/mach/i386/syscall_sw.h): "C#define syscall_class_none0/* Invalid */#define syscall_class_mach1/* Mach */#define syscall_class_unix2/* UNIX/BSD */#define syscall_class_mdep3/* machine-dependent */#define SYSCALL_CLASS_DIAG4/* Diagnostics * * * All MacOS system call list can be in [here] (https://opensource.apple.com/source/xnu/ xnu-1504.3.12/bsd/kern/syscalls.master) found. Parameters are passed to the system call through these registers ' DI ', ' SI ', ' DX ', ' R10 ', ' R8 ' and ' R9 ', the system call code is stored in ' AX '. NASM in the same way: "' Asmmov Rax, 0x2000004; Write system call mov rdi, 1; Parameter 1 FD (STDOUT) mov rsi, RCX; Parameter 2 Bufmov RDX, 16; Parameter 3 Countsyscall "In contrast, the similar example in Go ASM is like this:" Asmmovl $ $, DI//Parameter 1 FD (stdout) Leaq CX, SI//Parameter 2 BUFMOVL $16, DX//parameter 3 Countmovl $ (0x2000000+4), AX//write system call SYSCALL "" Similarly, the system call code is placed before the ' SYSCALL ' directive, which is just a generic notation, you can put the write system call directly in the NASM as in the front, No errors are reported after compilation. # # using Strings Now I believe you've been able to write some basic assembly code and run it, like the classic Hello world. We know how to pass a parameter to a child procedure, how to return a value, and if a symbol is defined within a data section. Have you ever tried to define a string? I had this problem when I was writing some assembly code a few days ago, and my biggest concern is, what can I do to define a fucking string? Well, you can define strings like this in NASM.: "' asmsection data:foo:db" My random string ", 0x00" but this is not in go, and after I delve into all the go ASM projects I can find online, I still can't find an example to define a simple string. Finally, I found an example in the Plan9 assembly language document, which shows how to get the target to be implemented. The only difference between Go and Plan9 is the use of double quotes instead of single quotes, and the addition of a ' rodata ' symbol: ' Asmdata foo<>+0x00 (SB)/8, $ "My rando" DATA foo<>+0x08 ( SB)/8, $ "m string" DATA foo<>+0x16 (SB)/1, $0x0aglobl foo<> (SB), Rodata, $24text HelloWorld (SB), Nosplit, $ 0MOVL $ (0x2000000+4), AX//Syscall WRITEMOVQ $, DI//ARG 1 Fdleaq foo<> (SB), SI//ARG 2 BUFMOVL $24, DX//ARG 3 Countsyscallret ' Note that when defining strings, they cannot be put together and need to be defined in 8-byte (64-bit) blocks. Now you can go into the go ASM world and write down your own super fast and extremely optimized code L, and remember to read those fucking manuals (smiling faces). # # used in the security field? Using the assembly in addition to optimizing your Go code, it is also easy to avoid triggering common signatures to circumvent antivirus software, and use some anti-compilation techniques to circumvent the sandbox to search for unusual behavior, or just let analysts whine. If you are interested in this, I will cover this topic in the next article, so stay tuned! # # Appendix-https://golang.org/doc/asm-https://9p.io/sys/doc/asm.pdf-https://goroutines.com/asm-https:// blog.sgmansfield.com/2017/04/a-foray-into-go-assembly-programming/
via:https://blog.hackercat.ninja/post/quick_intro_to_go_assembly/
Author: HCN Translator: Sunzhaohao proofreading: polaris1119
This article by GCTT original compilation, go language Chinese network honor launches
This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove
1427 reads ∙1 likes