SoFunction
Updated on 2025-03-03

Golang binary disassembly problem

Golang binary disassembly

Go's source code is a mixture of Plan 9 assembly and Go language, that is, assembly calls Go, and Go calls assembly.

In many cases, it is more intuitive to look at assembly code directly, especially when studying the implementation of compiler-generated functions.

The following are two disassembly methods:

Suppose there is a program, the source code is as follows:

package main

import "fmt"

func main() {
	("Hello, World!")
}

First compile the code into binary, the command is as follows:

go build --gcflags="-l -N" -o helloworld

A helloworld binary will be generated.--gcflags="-l -N"The function of the parameters is to remove compiler optimization, so that the generated assembly code is closer to the written code, and it is also convenient for GDB debugging.

Disassemble into AT&T assembly

AT&T is the most commonly used assembly language for Linux operating systems. The objdump tool provided by Linux system also decompiles binary into AT&T assembly. The commands are as follows:

objdump -d helloworld > 

The final disassembly results are placed in the file.

Here are the assembly results (partial code intercepted):

0000000000487200 <>:
  487200:   64 48 8b 0c 25 f8 ff    mov    %fs:0xfffffffffffffff8,%rcx
  487207:   ff ff  
  487209:   48 3b 61 10             cmp    0x10(%rcx),%rsp
  48720d:   76 7a                   jbe    487289 <+0x89>
  48720f:   48 83 ec 68             sub    $0x68,%rsp
  487213:   48 89 6c 24 60          mov    %rbp,0x60(%rsp)
  487218:   48 8d 6c 24 60          lea    0x60(%rsp),%rbp
  48721d:   0f 57 c0                xorps  %xmm0,%xmm0
  487220:   0f 11 44 24 38          movups %xmm0,0x38(%rsp)
  487225:   48 8d 44 24 38          lea    0x38(%rsp),%rax
  ...

Disassemble into Plan 9 assembly

Plan 9 is currently only used in Go language, and the online information is very scarce, and the learning cost is quite high. However, if you learn Plan 9 assembly, it will be very simple to look at the Go source code, and you can write efficient code through Go call assembly.

To disassemble binary into Plan 9 assembly, you can only use the tools provided by Go, the commands are as follows:

go tool objdump -S helloworld > 

The final disassembly results are placed in the file.

Here are the assembly results (partial code intercepted):

TEXT (SB) /root/program/golang/helloworld/
func main() {
  0x487200      64488b0c25f8ffffff  MOVQ FS:0xfffffff8, CX  
  0x487209      483b6110        CMPQ 0x10(CX), SP   
  0x48720d      767a            JBE 0x487289       
  0x48720f      4883ec68        SUBQ $0x68, SP      
  0x487213      48896c2460      MOVQ BP, 0x60(SP)   
  0x487218      488d6c2460      LEAQ 0x60(SP), BP   
    ("Hello, World!")
  0x48721d      0f57c0          XORPS X0, X0       
  0x487220      0f11442438      MOVUPS X0, 0x38(SP)     
  0x487225      488d442438      LEAQ 0x38(SP), AX       
  0x48722a      4889442430      MOVQ AX, 0x30(SP)

suggestion

Judging from the results shown above, the two assembly is still a bit different.

When learning Go source code, choosing which assembly to use to view this depends on your actual situation.

My suggestion is that you must have a certain understanding of AT&T assembly first, because there is too little information about Plan 9 assembly, and there is not even a complete introduction to the command. If a person without a compilation foundation reads some of the documents of Plan 9 directly, he will definitely look desperate.

When sorting out some Plan 9 compilation materials online, I found that they all talk about the differences between Plan 9 and AT&T, so only by understanding AT&T can you further learn Plan 9 compilation well.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.