go语言汇编(学习笔记)

GO语言汇编:plan9(贝尔操作系统)

go开发者与plan 9开发者同一人,Rob Pike

寄存器:

数据寄存器:R0-R7,地址寄存器:A0-A7,浮点寄存器:F0-F7。

伪栈寄存器:FP, SP, TOS

数据:

PC用来控制程序执行,SB用来引用全局变量。

Go语言汇编
FUNCDATA和PCDATA是编译器产生的,用于保存一些给垃圾收集的信息。

NOPTR和RODATA的数据不需要被垃圾收集。比指针还要小的数据也被当做NOPTR。不要在go汇编里写非只读数据。

plan9函数调用协议中采用的是caller-save的模式,也就是由调用者负责保存寄存器。

TEXT !$Add(SB),$0
MOVQ x+0(FP), BX
MOVQ y+8(FP), BP
ADDQ BP, BX
MOVQ BX, ret+16(FP)
RET

TEXT "".main(SB), $56-0
56 代表local 大小
0 代表args大小

movl 四字节mov intel指令集
movq 八字节

例子中的TEXT指令就定义了一个叫bytes·Equal的符号(注意是中点号·),接下来就是对应的指令(可以理解成函数体),而最后RET则是返回指令(退出当前stack)。通常情况下,参数大小后跟随着stack frame的大小,使用减号(-)分割。$0-49意味着这是一个0-byte的栈,并且有49-byte长的参数。NOSPLIT说明,不允许调度器调整stack frame的大小,这就意味着必须人工指定stack frame大小。

字符串 函数都放在SB stack basic register

堆栈函数调用.png

问题:
go是如何实现多值返回的?
go结构体是如何排布的?
go 数组入参的长度是多少?
如何查看go开辟空间位置 堆栈?
数组汇编是怎么玩的?

用例1:
代码:

    func fuck(a int){
        time.Sleep(time.Duration((a)))
    }
    func add(a,b int) int{
         //a = (b*2)
        fuck(a)
        return (a+b)
    }
    func main() {
        haha:=add(3,2)
        add(haha,4)
    }

asm:

    "".fuck t=1 size=65 args=0x4 locals=0x10
0x0000 00000 (myLove.go:10) TEXT    "".fuck(SB), $16-4
0x0000 00000 (myLove.go:10) MOVL    TLS, CX
0x0007 00007 (myLove.go:10) MOVL    (CX)(TLS*2), CX
0x000d 00013 (myLove.go:10) CMPL    SP, 8(CX)
0x0010 00016 (myLove.go:10) JLS 58
0x0012 00018 (myLove.go:10) SUBL    $16, SP
0x0015 00021 (myLove.go:10) FUNCDATA    $0, gclocals·5184031d3a32a42d85027f073f873668(SB)
0x0015 00021 (myLove.go:10) FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:11) MOVL    "".a+20(FP), AX
0x0019 00025 (myLove.go:11) CDQ
0x001a 00026 (myLove.go:11) MOVL    AX, "".autotmp_0+8(SP)
0x001e 00030 (myLove.go:11) MOVL    DX, "".autotmp_0+12(SP)
0x0022 00034 (myLove.go:11) MOVL    "".autotmp_0+8(SP), AX
0x0026 00038 (myLove.go:11) MOVL    AX, (SP)
0x0029 00041 (myLove.go:11) MOVL    "".autotmp_0+12(SP), AX
0x002d 00045 (myLove.go:11) MOVL    AX, 4(SP)
0x0031 00049 (myLove.go:11) PCDATA  $0, $0
0x0031 00049 (myLove.go:11) CALL    time.Sleep(SB)
0x0036 00054 (myLove.go:12) ADDL    $16, SP
0x0039 00057 (myLove.go:12) RET
0x003a 00058 (myLove.go:12) NOP
0x003a 00058 (myLove.go:10) CALL    runtime.morestack_noctxt(SB)
0x003f 00063 (myLove.go:10) JMP 0
0x0000 64 8b 0d 14 00 00 00 8b 89 00 00 00 00 3b 61 08  d............;a.
0x0010 76 28 83 ec 10 8b 44 24 14 99 89 44 24 08 89 54  v(....D$...D$..T
0x0020 24 0c 8b 44 24 08 89 04 24 8b 44 24 0c 89 44 24  $..D$...$.D$..D$
0x0030 04 e8 00 00 00 00 83 c4 10 c3 e8 00 00 00 00 eb  ................
0x0040 bf                                               .
rel 9+4 t=15 TLS+0
rel 50+4 t=7 time.Sleep+0
rel 59+4 t=7 runtime.morestack_noctxt+0
    "".add t=1 size=72 args=0xc locals=0x8
0x0000 00000 (myLove.go:13) TEXT    "".add(SB), $8-12
0x0000 00000 (myLove.go:13) MOVL    TLS, CX
0x0007 00007 (myLove.go:13) MOVL    (CX)(TLS*2), CX
0x000d 00013 (myLove.go:13) CMPL    SP, 8(CX)
0x0010 00016 (myLove.go:13) JLS 65
0x0012 00018 (myLove.go:13) SUBL    $8, SP
0x0015 00021 (myLove.go:13) FUNCDATA    $0, gclocals·790e5cc5051fc0affc980ade09e929ec(SB)
0x0015 00021 (myLove.go:13) FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:13) MOVL    $0, "".~r2+20(FP)
0x001d 00029 (myLove.go:15) MOVL    "".a+12(FP), BX
0x0021 00033 (myLove.go:15) MOVL    BX, (SP)
0x0024 00036 (myLove.go:15) PCDATA  $0, $0
0x0024 00036 (myLove.go:15) CALL    "".fuck(SB)
0x0029 00041 (myLove.go:16) MOVL    "".a+12(FP), BX
0x002d 00045 (myLove.go:16) MOVL    BX, "".autotmp_1+4(SP)
0x0031 00049 (myLove.go:16) MOVL    "".autotmp_1+4(SP), BX
0x0035 00053 (myLove.go:16) ADDL    "".b+16(FP), BX
0x0039 00057 (myLove.go:16) MOVL    BX, "".~r2+20(FP)
0x003d 00061 (myLove.go:16) ADDL    $8, SP
0x0040 00064 (myLove.go:16) RET
0x0041 00065 (myLove.go:16) NOP
0x0041 00065 (myLove.go:13) CALL    runtime.morestack_noctxt(SB)
0x0046 00070 (myLove.go:13) JMP 0
0x0000 64 8b 0d 14 00 00 00 8b 89 00 00 00 00 3b 61 08  d............;a.
0x0010 76 2f 83 ec 08 c7 44 24 14 00 00 00 00 8b 5c 24  v/....D$......\$
0x0020 0c 89 1c 24 e8 00 00 00 00 8b 5c 24 0c 89 5c 24  ...$......\$..\$
0x0030 04 8b 5c 24 04 03 5c 24 10 89 5c 24 14 83 c4 08  ..\$..\$..\$....
0x0040 c3 e8 00 00 00 00 eb b8                          ........
rel 9+4 t=15 TLS+0
rel 37+4 t=7 "".fuck+0
rel 66+4 t=7 runtime.morestack_noctxt+0
    "".main t=1 size=80 args=0x0 locals=0x10
0x0000 00000 (myLove.go:18) TEXT    "".main(SB), $16-0
0x0000 00000 (myLove.go:18) MOVL    TLS, CX
0x0007 00007 (myLove.go:18) MOVL    (CX)(TLS*2), CX
0x000d 00013 (myLove.go:18) CMPL    SP, 8(CX)
0x0010 00016 (myLove.go:18) JLS 73
0x0012 00018 (myLove.go:18) SUBL    $16, SP
0x0015 00021 (myLove.go:18) FUNCDATA    $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:18) FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:19) MOVL    $3, (SP)
0x001c 00028 (myLove.go:19) MOVL    $2, 4(SP)
0x0024 00036 (myLove.go:19) PCDATA  $0, $0
0x0024 00036 (myLove.go:19) CALL    "".add(SB)
0x0029 00041 (myLove.go:19) MOVL    8(SP), BX
0x002d 00045 (myLove.go:19) MOVL    BX, "".haha+12(SP)
0x0031 00049 (myLove.go:20) MOVL    "".haha+12(SP), BX
0x0035 00053 (myLove.go:20) MOVL    BX, (SP)
0x0038 00056 (myLove.go:20) MOVL    $4, 4(SP)
0x0040 00064 (myLove.go:20) PCDATA  $0, $0
0x0040 00064 (myLove.go:20) CALL    "".add(SB)
0x0045 00069 (myLove.go:21) ADDL    $16, SP
0x0048 00072 (myLove.go:21) RET
0x0049 00073 (myLove.go:21) NOP
0x0049 00073 (myLove.go:18) CALL    runtime.morestack_noctxt(SB)
0x004e 00078 (myLove.go:18) JMP 0
0x0000 64 8b 0d 14 00 00 00 8b 89 00 00 00 00 3b 61 08  d............;a.
0x0010 76 37 83 ec 10 c7 04 24 03 00 00 00 c7 44 24 04  v7.....$.....D$.
0x0020 02 00 00 00 e8 00 00 00 00 8b 5c 24 08 89 5c 24  ..........\$..\$
0x0030 0c 8b 5c 24 0c 89 1c 24 c7 44 24 04 04 00 00 00  ..\$...$.D$.....
0x0040 e8 00 00 00 00 83 c4 10 c3 e8 00 00 00 00 eb b0  ................
rel 9+4 t=15 TLS+0
rel 37+4 t=7 "".add+0
rel 65+4 t=7 "".add+0
rel 74+4 t=7 runtime.morestack_noctxt+0

用例二:
多值返回
代码:

    func add(a,b int) (int,int){
        //a = (b*2)
        fuck(a)
        return (a+b),(a-b)
    }
    func main() {
        haha,lala:=add(3,2)
        add(haha,lala)
    }

asm:

    "".main t=1 size=88 args=0x0 locals=0x18
0x0000 00000 (myLove.go:18) TEXT    "".main(SB), $24-0
0x0000 00000 (myLove.go:18) MOVL    TLS, CX
0x0007 00007 (myLove.go:18) MOVL    (CX)(TLS*2), CX
0x000d 00013 (myLove.go:18) CMPL    SP, 8(CX)
0x0010 00016 (myLove.go:18) JLS 81
0x0012 00018 (myLove.go:18) SUBL    $24, SP
0x0015 00021 (myLove.go:18) FUNCDATA    $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:18) FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:19) MOVL    $3, (SP)
0x001c 00028 (myLove.go:19) MOVL    $2, 4(SP)
0x0024 00036 (myLove.go:19) PCDATA  $0, $0
0x0024 00036 (myLove.go:19) CALL    "".add(SB)
0x0029 00041 (myLove.go:19) MOVL    8(SP), BX
0x002d 00045 (myLove.go:19) MOVL    BX, "".haha+20(SP)
0x0031 00049 (myLove.go:19) MOVL    12(SP), BX
0x0035 00053 (myLove.go:19) MOVL    BX, "".lala+16(SP)
0x0039 00057 (myLove.go:20) MOVL    "".haha+20(SP), BX
0x003d 00061 (myLove.go:20) MOVL    BX, (SP)
0x0040 00064 (myLove.go:20) MOVL    "".lala+16(SP), BX
0x0044 00068 (myLove.go:20) MOVL    BX, 4(SP)
0x0048 00072 (myLove.go:20) PCDATA  $0, $0
0x0048 00072 (myLove.go:20) CALL    "".add(SB)
0x004d 00077 (myLove.go:21) ADDL    $24, SP

    "".add t=1 size=100 args=0x10 locals=0xc
0x0000 00000 (myLove.go:13) TEXT    "".add(SB), $12-16
0x0000 00000 (myLove.go:13) MOVL    TLS, CX
0x0007 00007 (myLove.go:13) MOVL    (CX)(TLS*2), CX
0x000d 00013 (myLove.go:13) CMPL    SP, 8(CX)
0x0010 00016 (myLove.go:13) JLS 93
0x0012 00018 (myLove.go:13) SUBL    $12, SP

对比用例一与用例二的locals,发现add方法的locals扩大,其把入参与出参都当做返回值,处理。

用例三:研究一下结构体特点
代码:

    type test1 struct {
        a int
        b int
    }

    func f1(t1 test1){
        t1.a = 5
        fmt.Println(t1.a)
    }
    func main() {
        aa := test1{1,2}
        f1(aa)
    }

ASM:

    "".main t=1 size=94 args=0x0 locals=0x18
0x0000 00000 (myLove.go:14) TEXT    "".main(SB), $24-0
0x0000 00000 (myLove.go:14) MOVL    TLS, CX
0x0007 00007 (myLove.go:14) MOVL    (CX)(TLS*2), CX
0x000d 00013 (myLove.go:14) CMPL    SP, 8(CX)
0x0010 00016 (myLove.go:14) JLS 87
0x0012 00018 (myLove.go:14) SUBL    $24, SP
0x0015 00021 (myLove.go:14) FUNCDATA    $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:14) FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0015 00021 (myLove.go:15) MOVL    $0, BX
0x0017 00023 (myLove.go:15) MOVL    BX, "".aa+16(SP)
0x001b 00027 (myLove.go:15) MOVL    BX, "".aa+20(SP)
0x001f 00031 (myLove.go:15) MOVL    $1, "".autotmp_6+12(SP)
0x0027 00039 (myLove.go:15) MOVL    "".autotmp_6+12(SP), BX
0x002b 00043 (myLove.go:15) MOVL    BX, "".aa+16(SP)
0x002f 00047 (myLove.go:15) MOVL    $2, "".autotmp_7+8(SP)
0x0037 00055 (myLove.go:15) MOVL    "".autotmp_7+8(SP), BX
0x003b 00059 (myLove.go:15) MOVL    BX, "".aa+20(SP)
0x003f 00063 (myLove.go:16) MOVL    "".aa+16(SP), BX
0x0043 00067 (myLove.go:16) MOVL    BX, (SP)
0x0046 00070 (myLove.go:16) MOVL    "".aa+20(SP), BX
0x004a 00074 (myLove.go:16) MOVL    BX, 4(SP)
0x004e 00078 (myLove.go:16) PCDATA  $0, $0
0x004e 00078 (myLove.go:16) CALL    "".f1(SB)
0x0053 00083 (myLove.go:18) ADDL    $24, SP

    "".f1 t=1 size=200 args=0x8 locals=0x3c
0x0000 00000 (myLove.go:10) TEXT    "".f1(SB), $60-8
0x0000 00000 (myLove.go:10) MOVL    TLS, CX
0x0007 00007 (myLove.go:10) MOVL    (CX)(TLS*2), CX
0x000d 00013 (myLove.go:10) CMPL    SP, 8(CX)
0x0010 00016 (myLove.go:10) JLS 190
0x0016 00022 (myLove.go:10) SUBL    $60, SP
0x0019 00025 (myLove.go:10) FUNCDATA    $0, gclocals·8edb5632446ada37b0a930d010725cc5(SB)
0x0019 00025 (myLove.go:10) FUNCDATA    $1, gclocals·ff5e069297bc4e135ac51ef96d4582a2(SB)
0x0019 00025 (myLove.go:11) MOVL    $5, "".autotmp_5+24(SP)
0x0021 00033 (myLove.go:11) MOVL    "".autotmp_5+24(SP), BX
0x0025 00037 (myLove.go:11) MOVL    BX, "".t1+64(FP)
0x0029 00041 (myLove.go:12) MOVL    $0, BX
0x002b 00043 (myLove.go:12) MOVL    BX, "".autotmp_3+40(SP)
0x002f 00047 (myLove.go:12) MOVL    BX, "".autotmp_3+44(SP)
0x0033 00051 (myLove.go:12) LEAL    "".autotmp_3+40(SP), BX
0x0037 00055 (myLove.go:12) MOVL    BX, "".autotmp_1+28(SP)
0x003b 00059 (myLove.go:12) MOVL    $type.int(SB), (SP)
0x0042 00066 (myLove.go:12) LEAL    "".t1+64(FP), BX
0x0046 00070 (myLove.go:12) MOVL    BX, 4(SP)

main函数堆栈,将数值拷贝到偏移为0 和 4的位置,而f1函数直接从FP+64也就是SP+0的位置修改数据,所以数据修改无效
SP

     0---
     4---
    16---
    20---

FP

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 8086汇编 本笔记是笔者观看小甲鱼老师(鱼C论坛)《零基础入门学习汇编语言》系列视频的笔记,在此感谢他和像他一样...
    Gibbs基阅读 36,351评论 8 113
  • 原文: GCC-Inline-Assembly-HOWTO 1. 简介(Introduction.) 1.1 Co...
    桂糊涂阅读 4,467评论 1 5
  • 汇编总结 汇编的发展史 机械语言 由0和1组成的机器指令(如:0101 0001 1101 0110) 汇编语言(...
    iChuck阅读 1,261评论 1 8
  • 原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...
    小猪啊呜阅读 4,505评论 1 19
  • 当我第一次遇见你 我已被你如初生般的笑容捕获 我曾多次努力尝试忘却 但还是无法止住那涌动的泪水在眼中流淌 暗恋像蛇...
    一捧星团阅读 1,085评论 0 3