Parsing the function call of the Go language

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed. Let's take a look at a few simple examples of go function calls. By studying the assembly code generated by the go compiler for these functions, let's look at how function calls work. This topic is a little difficult for a little article, but don't worry, assembly language is very simple, even the CPU can understand it. [] (https://raw.githubusercontent.com/studygolang/gctt-images/master/anatomy-of-a-function/1_ Ckk4xrlm3ylzsqznboaroq.png) * Author: Rob Baines https://github.com/telecoda/inktober-2016* take a look at our first function, yes, we simply add two numbers. "' Gofunc Add (a, b int) int {return a + B} ' ' Through ' Go build-gcflags '-n-l ', we disable compilation optimizations to make the generated assembly code easier to read. Then we can use the Go tool ' Objdump-s main.add func ' (func is the name of the package that we use and the executable that the go build generates), and the assembly code that corresponds to the function is directed out. If you've never been in assembly language before, congratulations, now it's a new thing for you. I did the experiment on the Mac computer, so the assembler code is Intel 64 bit. "' Main.go:20 0x22c0 48c744241800000000 movq $0x0, 0x18 (sp) main.go:21 0x22c9 488b442408 movq 0x8 (sp), axmain.go:21 0x22ce 488b4c2410 movq 0x10 (sp), cxmain.go:21 0x22d3 4801c8 addq CX, axmain.go:21 0x22d6 4889442418 movq AX, 0x18 (sp) main.go:21 0x22db C3 RET ' ' What should we look at here? ' Each line is divided into the following four parts:-source file name and line number (MAIN.GO:15). The code for this line of source files is translated into a assembly instruction with line numbers. A line of Go can be translated into multiple lines of compilation. -The offset in the destination file (such as 0X22C0). -machine code (e.g. 48c744241800000000). This is the binary machine code that the CPU really executes. We're not going to see this part, and basically no one is going to see it. -assembly language representation of machine code. This is part of what we want to understand. Let's focus on the assembly code section. -Movq, ADDQ and RET are instructions. They tell the CPU what to do. Following the instruction is a parameter that tells the CPU who to operate on. -SP, AX, and CX are the registers of the CPU, where the CPU stores the variables used to work. In addition to these, the CPU will also use some other registers. -SP is a special register that stores the current stack pointer. A stack is an area of memory used to store local variables, function parameters, and function return addresses. Each goroutine corresponds to a stack. When a function calls another function, the called function continues to invoke another function, and each function gets a memory area on the stack. When a function is called, the value of the SP subtracts the stack space required by the called function, thus obtaining a block of memory to be used by the called function. -The 0x8 (SP) points to a location that is 8 bytes behind the memory location indicated by the SP. So, several elements include: memory location, CPU registers, instructions for moving data between memory and registers, and operations on registers. These are almost all of what the CPU does. Now let's take a detailed look at these assembly codes, starting with the first one. Remember that we have two parameters of ' a ' and ' B ' that need to be loaded from memory, added, and then returned. 1. ' Movq $0x0, 0x18 (SP) ' puts 0 in memory address sp+0x18. It seems a little mysterious. 2. ' Movq 0x8 (SP), ax ' places the contents of the memory address sp+0x8 into the CPU's AX register. Maybe that's one of the parameters that loads us from memory? 3. ' Movq 0x10 (SP), CX ' places the contents of the memory address sp+0x10 into the CX register of the CPU. This is another parameter of ours. 4. ' ADDQ cx, Ax ' adds CX to Microsoft Dynamics AX, leaving the results in Microsoft Dynamics AX. Well, it really does add up to two parameters. 5. ' Movq ax, 0x18 (SP) ' stores the content stored in AX in memory address sp+0x18. This is the process of storing the result of the addition. 6. ' RET ' returns to the calling function. Remember that our function has two parameters ' a ' and ' B ', it calculates ' a+b ' and returns the result. ' Movq 0x8 (SP), Ax ' is to move the parameter ' a ' to ax. ' A ' is passed into the function via the sp+0x8 position of the stack. ' Movq 0x10 (SP), CX ' moves the parameter ' B ' to CX. ' B ' is passed into the function via the sp+0x10 position of the stack. ' Addq CX, AX ' adds ' a ' and ' B '. ' Movq AX, 0x18 (SP) ' Saves the result to memory address sp+0x18. The result of the operation is passed to the calling function at the sp+0x18 of the stack. When the called function returns, the calling function reads the return value from the stack. [Here I assume that ' a ' is the first parameter, ' B ' is the second one. I'm not sure it's right. We may need more experimentation to find the right answer, but this article is long enough. So what's the first line that's a little esoteric? ' Movq $0x0, 0x18 (SP) ' stores 0 in memory address sp+0x18, noting that sp+0x18 is the address where the return value is stored. We can guess that this is because go is assigned a value of 0 for uninitialized variables. Even if it is not necessary, the compiler will do the same because we have disabled compilation optimizations. Let's see what we've learned. -it looks like the parameter is stored on the stack, the first parameter is in sp+0x8, and the other is at the next higher address. -The return value appears to be stored through the stack, at a higher address than the parameter. Now let's look at another function. This function has a local variable, but let's keep it as simple as possible. "' Gofunc add3 (a int) int {b: = 3return A + b} '" In the same way we get the following assembly code. "TEXT main.add3 (SB)/users/phil/go/src/github.com/philpearl/func/main.go main.go:15 0x2280 4883ec10 SUBQ $0x10, SP Main.go:15 0x2284 48896c2408 movq BP, 0x8 (sp) main.go:15 0x2289 488d6c2408 leaq 0x8 (sp), BP main.go:15 0x228e 48c744242000 000000 movq $0x0, 0x20 (sp) main.go:16 0x2297 48c7042403000000 movq $0x3, 0 (sp) main.go:17 0x229f 488b442418 MOVQ 0x18 (sp), Ax main.go:17 0x22a4 4883c003 addq $0x3, ax main.go:17 0x22a8 48894424Movq AX, 0x20 (sp) main.go:17 0x22ad 488b6c2408 movq 0x8 (sp), BP main.go:17 0x22b2 4883c410 addq $0x10, SP main.go:17 0x 22B6 C3 RET ' Ah, it looks more complicated than the last. Let's try to understand it. The first four instructions correspond to the source code of line 15th. This line is: "' Gofunc add3 (a int) int {" "This line does not look too much. So this could be some kind of "prologue" to the function. Let's break it down a bit. -' Subq $0x10, SP ' subtracts the SP's value from 0x10, which is 16. This increases the stack space by 16 bytes. -' Movq BP, 0x8 (SP) ' stores the value of the register BP in sp+8 position, ' Leaq 0x8 (sp), BP ' stores the corresponding address of the sp+8 in BP. This helps us set up the chain of stack space (stack frame). It's a bit of a mystery, but I'm afraid this article won't explain it. -The end of this section is ' Movq $0x0, 0x20 (SP) '. This is similar to the previous function we just discussed, which is to initialize the return value to 0. The next line of the assembly corresponds to the ' B: = 3 ' of the source code. This command ' Movq $0x3, 0 (SP) ' puts 3 into memory sp+0. This solves our doubts. When we subtract the SP's value from 0x10=16, we empty the space to accommodate 2 8-byte variables: local variable ' b ' is stored in sp+0, and BP's value is stored in sp+0x8. The following 6 lines correspond to ' return a + B '. This includes loading ' a ' and ' B ' from memory, adding them together, and returning the results of the calculation. Let's look at each line in order. -' movq 0x18 (SP), AX ' moves the parameter ' a ' stored at sp+0x18 to register ax. -' ADDQ $0x3, Ax ' adds 3 to the value of ax (although we turned off the optimization option, but for some reason there is still no use of local variable ' b ' stored in sp+0). -' Movq AX, 0x20 (SP) ' stores the results of ' a+b ' in sp+0x20, where our return values are stored. -Next is ' movq 0x8 (sp), BP ' and ' addq $0x10, SP '. The value of the BP is restored first, then the value of the SP is increased to 0x10 so that the SP is restored to the beginning of the function. The value. -Finally, ' RET ', returned to the calling function. So what have we learned? -The caller function applies a space on the stack for the return value and parameters. The address of the return value on the stack is higher than the parameter. -If the called function has a local variable, it will request space by reducing the value of the stack pointer SP. This also has some wonderful relationships with register BP. -When the function returns, all operations on both SP and BP are rolled back. Let's draw out how ADD3 () is using the stack: "sp+0x20: Return value sp+0x18: Parameter a sp+0x10:?? SP+0X08:BP Original value sp+0x0: local variable B ' ' We don't see any mention of sp+0x10, so we don't know what it's for. But I can tell you that this stores the address returned by the function. This ' RET ' command only knows where to go. Well, it's enough for this article. If you don't know how these things work before, then hopefully you understand a little bit now. If you have been intimidated by the Assembly, and hope now it is no longer so obscure to you. If you want to know more details, you can write a comment and I'll consider writing a more detailed article later. If you like this article, or learn something from it, please praise it so that other people can see it.

Via:https://syslog.ravelin.com/anatomy-of-a-function-call-in-go-f6fc81b80ecc

Author: Phil Pearl Translator: Krystollia proofreading: Rxcai

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

484 Reads

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.