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閱讀 228,702評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內容

  • 8086匯編 本筆記是筆者觀看小甲魚老師(魚C論壇)《零基礎入門學習匯編語言》系列視頻的筆記,在此感謝他和像他一樣...
    Gibbs基閱讀 37,304評論 8 114
  • 原文: GCC-Inline-Assembly-HOWTO 1. 簡介(Introduction.) 1.1 Co...
    桂糊涂閱讀 4,554評論 1 5
  • 匯編總結 匯編的發展史 機械語言 由0和1組成的機器指令(如:0101 0001 1101 0110) 匯編語言(...
    iChuck閱讀 1,313評論 1 8
  • 原文地址:C語言函數調用棧(一)C語言函數調用棧(二) 0 引言 程序的執行過程可看作連續的函數調用。當一個函數執...
    小豬啊嗚閱讀 4,655評論 1 19
  • 當我第一次遇見你 我已被你如初生般的笑容捕獲 我曾多次努力嘗試忘卻 但還是無法止住那涌動的淚水在眼中流淌 暗戀像蛇...
    一捧星團閱讀 1,142評論 0 3