Skip to content

Go汇编学习 1.进程内存地址与寄存器

前言

本文是我学习Go汇编的一些心得,网上关于Go的汇编资料实在是太少了,本人计算机不是科班,所以__可能会有错误__。

进程内存地址空间

操作系统执行程序时,会把程序的二进制部分加载进内存,同时分配一定的内存空间。如下图所示

TEXT/Code segment

TEXT segment,或者叫Code segment,保存了程序的指令。

  • 只能执行
  • 固定长度

Data segment

Data segment 保留着进程初始化的全局和静态的变量。这个数据段可以变为初始化只读区域(initialized read-only area)和初始化读写区域(initialized read-write area)。

Gvar Section

一个全局变量初始化和存储在data segment。这个区域可读/写,但是不能在进程之间共享数据。

BSS Section

这个section保存着未初始化的数据。 这个section的又叫做零初始化数据section(zero-initialized data section)

Heap Section

heap是进程的线性增长地址空间,当程序使用malloc()获取的动态内存,这份内存就是在heap之中。heap区域是在BSS segement之后,并会“增长”到更高的地址空间。heap区域是所有共享库、动态模块都可见的。

  • 可读写
  • 变量大小
  • 请求之后动态分配,需要自己释放

Stack Segment

这个Segement保存所有局部变量。当调用函数时,这个函数的局部变量就全部分布在stask上(这个函数就形成了stack frame)。当函数退出时,所有该函数相关的局部变量会自动从stask上退出。其他信息,包括返回地址和局部参数,也是保存在stack的stack frame之上。stack是LIFO(last in first out 先进后出)结构,一般是分配在内存的高地址上,因此是向低位增长,还有每个寄存器,中间值或者stack frame。

  • 可读写
  • 变量大小
  • 动态增长\缩小

跟Go asm有什么关系?

Go有几个虚拟寄存器

  • FP (stack frame pointer) stack帧低位指针,指向参数和局部变量,offset为正数
  • SP(virtual stack pointer)stack帧高位指针(栈顶),offset应为负数
  • PC (program counter) 程序计数器,负责跳转和分支
  • SB (static base pointer) 静态全局符号(symbol)

其中FP和SP的区别如下图所示:


High +-----------------+
| |
| Stack frame 0 |
| |
+-----------------+
| | <---+ SP
| Stack frame 1 |
| | <---+ FP
Low +-----------------+

这里有个疑问的地方,啥是符号(symbol),根据Symbol里的解释是:

符号(symbol)是帮助人们标记特定内存地址的东西

也就是说例如

TEXT DEMO(SB)

就代表指向code segment中代表DEMO函数的内存地址。

寄存器

每种CPU都有不同的寄存器,AMD64平台里常用的有以下几个:

  • [A-D]X //通用的64位寄存器
  • R8-15 // 之前的其实是A-Dx、SI、DI等寄存器占用了
  • SI // 源(source register)
  • DI // 目的地 (destination register)
  • X0-15 // sse用
  • Y0-15 // avx2 用

了解完内存结构和寄存器后,下一篇将学习各种符号的意义:)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.