第1节 Gcc and Cgo

❤️💕💕Go语言高级篇章,在此之前建议您先了解基础和进阶篇。Myblog:http://nsddd.topopen in new window

Go语言基础篇open in new window

Go语言100篇进阶open in new window


[TOC]


我们默认为是C语言是占4个字节,这个和Go语言是不一样的。

在Go语言中,int默认是8个字节

  • int32是四个字节
  • int64是八个字节
  • int是八个字节
/*************************************************************************
    > File Name: a.go
    > Author: smile
    > Mail: 3293172751nss@gmail.com 
    > Created Time: Thu 30 Jun 2022 01:13:35 AM PDT
 ************************************************************************/
package main
import(
    "fmt"
)

func main(){
    var(
    a = 40000
    b = 50000
)
var c int
var d int32
    c = 50000
    d = 50000
    fmt.Println(a*a)
    fmt.Println(b*b)
    fmt.Println(c*c)
    fmt.Println(d*d)
}

我们对上面的代码进行编译:

root@ubuntu:/c# go run a.go 
1600000000
2500000000
2500000000
-1794967296

对于C语言来说

编译为汇编文件

root@ubuntu:/c# gcc -S a.c
root@ubuntu:/c# cat a.s
	.file	"a.c"
	.text
	.section	.rodata
.LC0:
	.string	"%d\n,%d\n"
.LC1:
	.string	"int c = %d\n,int64_t d = %lld\n"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$32, %rsp
	movl	$50000, -20(%rbp)
	movl	$40000, -16(%rbp)
	movl	-16(%rbp), %eax
	imull	%eax, %eax
	movl	%eax, %edx
	movl	-20(%rbp), %eax
	imull	%eax, %eax
	movl	%eax, %esi
	leaq	.LC0(%rip), %rdi
	movl	$0, %eax
	call	printf@PLT
	movq	-8(%rbp), %rax
	imulq	%rax, %rax
	movq	%rax, %rdx
	movl	-12(%rbp), %eax
	imull	%eax, %eax
	movl	%eax, %esi
	leaq	.LC1(%rip), %rdi
	movl	$0, %eax
	call	printf@PLT
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	 1f - 0f
	.long	 4f - 1f
	.long	 5
0:
	.string	 "GNU"
1:
	.align 8
	.long	 0xc0000002
	.long	 3f - 2f
2:
	.long	 0x3
3:
	.align 8
4:

编译为二进制代码

root@ubuntu:/c# gcc -Og -c a.c
root@ubuntu:/c# cat a.o                                                                E¹^_º򔈍5¿¸蹺H5¿¸.ed
,%d
int c = %d
,int64_t d = %lld
GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0GNU󿾄zRx 
                                                H򽁁                                     R*a.c.LC0.LC1main_GLOBAL_OFFSET_TABLE___printf_chk	񁀿ÿÿ$񁀿ÿÿ5 
񁀿ÿÿD񁀿ÿÿ .symtab.strtab.shstrtab.rela.text.data.bss.rodata.str1.1.comment.note.GNU-stack.note.gnu.property.rela.eh_frame @Rւ`
                                   &12&@0¸,Il@8 
                                               8h 

                                                	 7P{root@ubuntu:/c# XshellXshellXshellXshellXshell
XshellXshellXshellXshellXshell: command not found

.o后缀的文件是二进制格式的,没有查看意义,我们可以得出:机器执行的程序只是一个字节序列, 它是对一系列指令的编码。机器对产生这些指令的源代码几乎一无所知。

如果需要显示出机器代码文件的内容,我们需要用到反汇编器(这个程序非常有用),在Linux中-d指令标志的objdump 可以充当这个角色

root@ubuntu:/c# objdump -d a.o

a.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:	f3 0f 1e fa          	endbr64 
   4:	48 83 ec 08          	sub    $0x8,%rsp
   8:	b9 00 10 5e 5f       	mov    $0x5f5e1000,%ecx
   d:	ba 00 f9 02 95       	mov    $0x9502f900,%edx
  12:	48 8d 35 00 00 00 00 	lea    0x0(%rip),%rsi        # 19 <main+0x19>
  19:	bf 01 00 00 00       	mov    $0x1,%edi
  1e:	b8 00 00 00 00       	mov    $0x0,%eax
  23:	e8 00 00 00 00       	callq  28 <main+0x28>
  28:	b9 00 00 00 00       	mov    $0x0,%ecx
  2d:	ba 00 00 00 00       	mov    $0x0,%edx
  32:	48 8d 35 00 00 00 00 	lea    0x0(%rip),%rsi        # 39 <main+0x39>
  39:	bf 01 00 00 00       	mov    $0x1,%edi
  3e:	b8 00 00 00 00       	mov    $0x0,%eax
  43:	e8 00 00 00 00       	callq  48 <main+0x48>
  48:	b8 00 00 00 00       	mov    $0x0,%eax
  4d:	48 83 c4 08          	add    $0x8,%rsp
  51:	c3                   	retq   

对于Go语言我们同样可以使用反汇编命令

root@ubuntu:/c# go build -o a a.go
root@ubuntu:/c# ./a
1600000000
2500000000
2500000000
-1794967296
root@ubuntu:/c# objdump -d a | tail -n 10
  48d03c:	00 00 
  48d03e:	48 c7 44 24 20 01 00 	movq   $0x1,0x20(%rsp)
  48d045:	00 00 
  48d047:	e8 a4 96 ff ff       	callq  4866f0 <fmt.Fprintln>
  48d04c:	48 8b ac 24 80 00 00 	mov    0x80(%rsp),%rbp
  48d053:	00 
  48d054:	48 81 c4 88 00 00 00 	add    $0x88,%rsp
  48d05b:	c3                   	retq   
  48d05c:	e8 2f 47 fc ff       	callq  451790 <runtime.morestack_noctxt>
  48d061:	e9 2a fe ff ff       	jmpq   48ce90 <main.main>

END 链接