美文网首页
go plan 9汇编

go plan 9汇编

作者: 链人成长chainerup | 来源:发表于2019-07-16 22:55 被阅读0次

本文将简单介绍一下go语言的汇编。
主要的内容如下:

  • plan 9 是什么?为什么学习plan9?
  • plan9 的常见指令
  • go程序如何转换为plan9 ?
    下面就开始简单介绍一下。

plan 9 是什么?为什么学习plan9?

plan9, Go一套自己的汇编。按照官方文档的说法,其设计初衷是解决跨平台的问题,但是没有做好。并且它不同于传统的汇编,也就是说要想学习go汇编,你需要重新学习一套语法。社区在争论这个问题,有人说是因为go的几个大佬,原来是用plan9的。这个问题咱们这儿不讨论。
那作为普通人,我们学汇编干啥呢?
装逼!这是第一生产力!我一直有一个不成熟的想法,希望自己能够像机器一样看穿代码的运行。有时想想,也挺可笑的。
除了装逼,真的一点用处都没有了吗?
当然不是!!!
说下我能想到的几个点:

  • 确定一段代码底层执行了什么函数
  • 查看基础的数据结构的运行机制
  • 查看内存的分配
  • 查看go在函数头和函数尾插入的相关的调度
    ...
    难道这几条还不够吗?

plan9 的常见指令

其实汇编跟java, go等语言 没啥区别,无非也是变量、方法等。只是我们做应用层开发不常用而已。如果懂了基础的语法,其实也就这样。下面列几个常用的指令,看不懂也没事,多看几遍就知道了,其实我也不是很熟,啥时候真用到,再回来看也行。

栈扩大、缩小

plan9 中栈操作并没有使用push,pop,而是采用sub 跟add SP。

SUBQ $0x18, SP // 对 SP 做减法,为函数分配函数栈帧
ADDQ $0x18, SP // 对 SP 做加法,清除函数栈帧

数据copy

MOVB $1, DI      // 1 byte 
MOVW $0x10, BX   // 2 bytes
MOVD $1, DX      // 4 bytes
MOVQ $-10, AX     // 8 bytes

计算指令

ADDQ  AX, BX   // BX += AX
SUBQ  AX, BX   // BX -= AX
IMULQ AX, BX   // BX *= AX

跳转

// 无条件跳转
JMP addr   // 跳转到地址,地址可为代码中的地址,不过实际上手写不会出现这种东西
JMP label  // 跳转到标签,可以跳转到同一函数内的标签位置
JMP 2(PC)  // 以当前指令为基础,向前/后跳转 x 行
JMP -2(PC) // 同上
// 有条件跳转
JNZ target // 如果 zero flag 被 set 过,则跳转

变量声明

在汇编里所谓的变量,一般是存储在 .rodata 或者 .data 段中的只读值。对应到应用层的话,就是已初始化过的全局的 const、var、static 变量/常量。

DATA    symbol+offset(SB)/width, value

使用 DATA 结合 GLOBL 来定义一个变量
GLOBL 必须跟在 DATA 指令之后:

DATA age+0x00(SB)/4, $18  // forever 18
GLOBL age(SB), RODATA, $4

DATA pi+0(SB)/8, $3.1415926
GLOBL pi(SB), RODATA, $8

DATA birthYear+0(SB)/4, $1988
GLOBL birthYear(SB), RODATA, $4

函数声明

先看一个定义:

// func add(a, b int) int
//   => 该声明定义在同一个 package 下的任意 .go 文件中
//   => 只有函数头,没有实现
TEXT pkgname·add(SB), NOSPLIT, $0-8
    MOVQ a+0(FP), AX
    MOVQ a+8(FP), BX
    ADDQ AX, BX
    MOVQ BX, ret+16(FP)
    RET

代码存储在TEXT段中。
pkgname 可以省略。
比如你的方法是 runtime·main,在编译之后的程序里的符号则是 runtime.main。

                             参数及返回值大小
                                  | 
 TEXT pkgname·add(SB),NOSPLIT,$32-32
       |        |               |
      包名     函数名         栈帧大小(局部变量+可能需要的额外调用函数的参数空间的总大小,但不包括调用其它函数时的 ret address 的大小)

寄存器

有4个核心的伪寄存器,这4个寄存器是编译器用来维护上下文、特殊标识等作用的:

FP(Frame pointer): arguments and locals
PC(Program counter): jumps and branches
SB(Static base pointer): global symbols
SP(Stack pointer): top of stack

还有很多其他的用法,就先不摘抄了,后面用到再去查吧。

go程序如何转换为plan9 ?

// 编译
go build -gcflags="-S"
go tool compile -S hello.go
go tool compile -N -S hello.go // 禁止优化
// 反编译
go tool objdump <binary>

总结与后记

本文简单的讲述了plan9 是什么?什么用途? 也罗列了几个plan9 常见的指令,增加自信。最后简单的几行指令,教你如何看某一段代码的plan9 指令。
如果时间允许,会结合前人的文章,针对go中常见的类型、api操作、内存分配、channel 等进行汇编指令级的学习,给自己加油~

参考文献

1、汇编 is so easy
2、Go 系列文章3 :plan9 汇编入门
3、golang内核系列--深入理解plan9汇编&实践

相关文章

  • go 的汇编代码

    plan9汇编 Go汇编语言实际上来源于plan9汇编语言,而plan9汇编语言最初来源于Go语言作者之一的Ken...

  • go plan 9汇编

    本文将简单介绍一下go语言的汇编。主要的内容如下: plan 9 是什么?为什么学习plan9?plan9 的常见...

  • go语言汇编(学习笔记)

    GO语言汇编:plan9(贝尔操作系统) go开发者与plan 9开发者同一人,Rob Pike 寄存器: 数据寄...

  • Design a plan

    2.4 Design a plan. 规划方案 a.Go back before you go forward. ...

  • My  2016

    Today is the last day of 2016, go back to the plan at the...

  • 2016.7.16英语作文

    My classmates and I plan to go to nursing home to spend w...

  • 2018-08-08

    go 汇编 编译一个最简单的go执行程序 go build -gcflags "-N -l" test.go 使用...

  • 懂你笔记-6-2-1

    Vacation plan So, where should we go on our vacation?那么,我...

  • Go to Market Plan

    市场估计:10M$ -金融机构,跨国科技企业,海外并购国企等大B端企业,对于海外专家需求预计5-10M$ -科技企...

  • darkness

    today go to bed will be late,today's plan don't have do...

网友评论

      本文标题:go plan 9汇编

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