美文网首页go
Go中全局变量存储在哪里?

Go中全局变量存储在哪里?

作者: 沙漠中的猴 | 来源:发表于2018-08-14 20:01 被阅读0次

创建一个src.go文件,加入下面的代码

package main

import "fmt"

var xxx = 0xEE     // 通过值来推断类型
var yyy int = 0xFF // 定义类型,并赋值
var zzz int        // 定义变量

func main() {
    xxx = 0x11
    yyy = 0x22
    zzz = 0x33

    fmt.Println(xxx, yyy, zzz)
}

然后在命令行输入

go build -gcflags "-N -l"

-N 关闭编译器优化
-l 关闭内联

gdb调试

进入gdb模式

gdb src

设置断点

(gdb) b 14     // 在第十四行设置断点

运行程序

(gdb) r

设置汇编语言为intel

(gdb) set disassembly-flavor intel

输入

(gdb) disass

来查看变量分配的地址。

(gdb) set disassembly-flavor intel
(gdb) disass
Dump of assembler code for function main.main:
   0x00000000004820f0 <+0>: mov    rcx,QWORD PTR fs:0xfffffffffffffff8
   0x00000000004820f9 <+9>: lea    rax,[rsp-0x38]
   0x00000000004820fe <+14>:    cmp    rax,QWORD PTR [rcx+0x10]
   0x0000000000482102 <+18>:    jbe    0x4822d1 <main.main+481>
   0x0000000000482108 <+24>:    sub    rsp,0xb8
   0x000000000048210f <+31>:    mov    QWORD PTR [rsp+0xb0],rbp
   0x0000000000482117 <+39>:    lea    rbp,[rsp+0xb0]
   0x000000000048211f <+47>:    mov    QWORD PTR [rip+0x91f96],0x11        # 0x5140c0 <main.xxx>
   0x000000000048212a <+58>:    mov    QWORD PTR [rip+0x91f93],0x22        # 0x5140c8 <main.yyy>
   0x0000000000482135 <+69>:    mov    QWORD PTR [rip+0xc1d00],0x33        # 0x543e40 <main.zzz>
=> 0x0000000000482140 <+80>:    xorps  xmm0,xmm0

我们可以看到:

  • xxx地址为0x5140c0
  • yyy地址为0x5140c8
  • zzz地址为0x543e40

他们分别位于哪个段(Section)呢?

我们输入如下命令来查看所处的位置

(gdb) info symbol 0x5140c0
main.xxx in section .noptrdata of /root/go/src/src
(gdb) info symbol 0x5140c8
main.yyy in section .noptrdata of /root/go/src/src
(gdb) info symbol 0x543e40
main.zzz in section .noptrbss of /root/go/src/src

我们可以看到xxx与yyy位于.noptrdata段(Section)内。zzz位于.noptrbss段(Section)内

由于go有垃圾回收器,所以将.data段(Section)去分为有指针和无指针两个段(Section)

如何查看段(Section)分配的空间大小?

(gdb) info files
Symbols from "/root/go/src/src".
Native process:
    Using the running image of child LWP 4272.
    While running this, GDB does not access memory from...
Local exec file:
    `/root/go/src/src', file type elf64-x86-64.
    Entry point: 0x44f550
    0x0000000000401000 - 0x0000000000482505 is .text
    0x0000000000483000 - 0x00000000004c4a7e is .rodata
    0x00000000004c4ba0 - 0x00000000004c56e8 is .typelink
    0x00000000004c56e8 - 0x00000000004c5728 is .itablink
    0x00000000004c5728 - 0x00000000004c5728 is .gosymtab
    0x00000000004c5740 - 0x0000000000513947 is .gopclntab
    0x0000000000514000 - 0x0000000000520bfc is .noptrdata
    0x0000000000520c00 - 0x0000000000527710 is .data
    0x0000000000527720 - 0x0000000000543da8 is .bss
    0x0000000000543dc0 - 0x0000000000546458 is .noptrbss
    0x0000000000400f9c - 0x0000000000401000 is .note.go.buildid
    0x00007ffff7ffd120 - 0x00007ffff7ffd15c is .hash in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd160 - 0x00007ffff7ffd1a8 is .gnu.hash in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd1a8 - 0x00007ffff7ffd298 is .dynsym in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd298 - 0x00007ffff7ffd2f6 is .dynstr in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd2f6 - 0x00007ffff7ffd30a is .gnu.version in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd310 - 0x00007ffff7ffd348 is .gnu.version_d in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd348 - 0x00007ffff7ffd478 is .dynamic in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd478 - 0x00007ffff7ffd7b8 is .rodata in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd7b8 - 0x00007ffff7ffd7f4 is .note in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd7f4 - 0x00007ffff7ffd830 is .eh_frame_hdr in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd830 - 0x00007ffff7ffd948 is .eh_frame in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffd950 - 0x00007ffff7ffdde9 is .text in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffdde9 - 0x00007ffff7ffde1d is .altinstructions in system-supplied DSO at 0x7ffff7ffd000
    0x00007ffff7ffde1d - 0x00007ffff7ffde29 is .altinstr_replacement in system-supplied DSO at 0x7ffff7ffd000

如何查看段(Section)的权限?

root@000d3fada0b3:~/go/src# readelf -S src
There are 23 section headers, starting at offset 0x1c8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000401000  00001000
       0000000000081505  0000000000000000  AX       0     0     16
  [ 2] .rodata           PROGBITS         0000000000483000  00083000
       0000000000041a7e  0000000000000000   A       0     0     32
  [ 3] .shstrtab         STRTAB           0000000000000000  000c4a80
       000000000000010b  0000000000000000           0     0     1
  [ 4] .typelink         PROGBITS         00000000004c4ba0  000c4ba0
       0000000000000b48  0000000000000000   A       0     0     32
  [ 5] .itablink         PROGBITS         00000000004c56e8  000c56e8
       0000000000000040  0000000000000000   A       0     0     8
  [ 6] .gosymtab         PROGBITS         00000000004c5728  000c5728
       0000000000000000  0000000000000000   A       0     0     1
  [ 7] .gopclntab        PROGBITS         00000000004c5740  000c5740
       000000000004e207  0000000000000000   A       0     0     32
  [ 8] .noptrdata        PROGBITS         0000000000514000  00114000
       000000000000cbfc  0000000000000000  WA       0     0     32
  [ 9] .data             PROGBITS         0000000000520c00  00120c00
       0000000000006b10  0000000000000000  WA       0     0     32
  [10] .bss              NOBITS           0000000000527720  00127720
       000000000001c688  0000000000000000  WA       0     0     32
  [11] .noptrbss         NOBITS           0000000000543dc0  00143dc0
       0000000000002698  0000000000000000  WA       0     0     32
  [12] .debug_abbrev     PROGBITS         0000000000547000  00128000
       00000000000001b5  0000000000000000           0     0     1
  [13] .debug_line       PROGBITS         00000000005471b5  001281b5
       00000000000106e8  0000000000000000           0     0     1
  [14] .debug_frame      PROGBITS         000000000055789d  0013889d
       00000000000120dc  0000000000000000           0     0     1
  [15] .debug_pubnames   PROGBITS         0000000000569979  0014a979
  • A 是否载入内存
  • W 是否可写
  • X 执行权限

总结

初始化的全局变量分配在.data段(Section)内
未初始化的全局变量分配在.bss段(Section)内

局部变量在程序运行时分配内存地址。

如何对src文件反汇编?

go tool objdump -s "main\.main" src

相关文章

  • Go中全局变量存储在哪里?

    创建一个src.go文件,加入下面的代码 然后在命令行输入 -N 关闭编译器优化-l 关闭内联 gdb调试 进入g...

  • 全局变量和静态全局变量的区别

    相同点: 存储区域相同:全局变量和静态全局变量都存放在静态存储区。生命周期相同:全局变量和静态全局变量的都是在程序...

  • 局部变量和全局变量

    什么是局部变量? 在Go语言和C语言中写在{}中或者函数中或者函数的形参, 就是局部变量 什么是全局变量? 在Go...

  • static

    修饰全局变量 在全局变量前加static,全局变量就被定义成为一个全局静态变量 特点如下: 1)存储区:静态存储区...

  • React Native 全局变量Global

    1. 什么是全局变量 简单来说,全局变量就是整个源程序都有效的变量。全局变量存储在全局数据区中,它的生命周期和...

  • 小程序如何传递数据

    1、本地缓存 2、全局变量: 在 app.js 中的 this.globalData = { } 中放入要存储的...

  • 【C语言】10.static&extern,typede

    全局变量:程序一启动就会分配空间,直到程序结束。存储位置在静态存储区。多个同名的全局变量指向同一块存储空间。全局变...

  • 图解简单C程序的运行时结构

    程序在内存中的存储分为三个区域,分别是动态数据区、静态数据区和代码区。函数存储在代码区,全局变量以及静态变量存储在...

  • 四、Go语言变量作用域

    四、Go语言变量作用域 全局变量 在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使...

  • OC中的static

    不能修饰成员变量 ×可以修饰局部变量 存储到静态存储区全局变量 只能在当前源文件中访问函数 ...

网友评论

    本文标题:Go中全局变量存储在哪里?

    本文链接:https://www.haomeiwen.com/subject/vlgvbftx.html