
ã©ã³ã¿ã€ã ãå®è£
ããŠæšæºã©ã€ãã©ãªãåŠç¿ããåã«ãæœè±¡ã¢ã»ã³ãã©Goããã¹ã¿ãŒããå¿
èŠããããŸãã ãã®ã¬ã€ãããå¿
èŠãªç¥èããã°ããåŸãã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
å
容ãã®èšäºã¯ãèªè
ãããããçš®é¡ã®ã¢ã»ã³ãã©ãŒã®åºæ¬çãªç¥èãæã£ãŠããããšãåæãšããŠããŸãã
ã¢ãŒããã¯ãã£é¢é£ã®åé¡ã«ãªããšãlinux / amd64ã®äœ¿çšãåžžã«æç€ºãããŸãã
ç§ãã¡ã¯ãåžžã«å«ãŸããã³ã³ãã€ã©ã®æé©åã䜿çšããŸãã
ãã¹ãŠã®åŒçšã¯ãç¹ã«æèšããªãéããå
¬åŒææžããã³/ãŸãã¯ã³ãŒãããŒã¹ããã®ãã®ã§ããç䌌ã¢ã»ã³ãã©ãŒ
Goã³ã³ãã€ã©ãŒã¯ãããŒããŠã§ã¢ã«çžãããªãæœè±¡çã§ããŒã¿ãã«ãªã¢ã»ã³ãã©ãŒãçæããŸãã æ¬¡ã«ãã¢ã»ã³ãã©ãŒGoã¯ãã®æ¬äŒŒã¢ã»ã³ãã©ãŒã䜿çšããŠãã¿ãŒã²ããæ©åšçšã®ãã·ã³åºæã®åœä»€ãçæããŸãã
ãã®è¿œå ã®ãã¬ãã«ãã«ã¯å€ãã®å©ç¹ããããŸãã äž»ãªãã®ã¯ãGoãæ°ããã¢ãŒããã¯ãã£ã«ç°¡åã«ç§»æ€ã§ããããšã§ãã 詳现ã«ã€ããŠã¯ãRob Pikeã®ããã©ãŒãã³ã¹ã
The Design of the Go Assembler ãããéãããŸãã
Goã¢ã»ã³ãã©ã«ã€ããŠç¥ã£ãŠããå¿
èŠãããæãéèŠãªããšã¯ããããèšèªã®åºã«ãªããã·ã³ãçŽæ¥è¡šçŸããŠããªãããšã§ãã äœãããã·ã³ã«çŽæ¥ãããã³ã°ãããäœãã¯ããã§ã¯ãããŸããã å®éãã³ã³ãã€ã©ã¯ã¢ã»ã³ãã©ãéåžžã®ãã€ãã©ã€ã³ã«æž¡ãå¿
èŠã¯ãããŸããã 代ããã«ãã³ã³ãã€ã©ãŒã¯ãã³ãŒãã®çæåŸã«éšåçã«éžæãããåœä»€ã®åæœè±¡ã»ããã§åäœããŸãã ã¢ã»ã³ãã©ã¯åæœè±¡åœ¢åŒã§åäœãããããMOVåœä»€ã衚瀺ãããŠããããŒã«ãããããã®æäœã®ç§»ååœä»€ãçæããããšã«ã¯ãªããŸããã ãããããããã¯ã¯ãªãŒãã³ã°ãŸãã¯ããŒãã®æç€ºã«ãªããŸãã ãŸãã¯ãçæãããåœä»€ã¯ãåãååã®ãã·ã³åœä»€ãšå®å
šã«äžèŽããå ŽåããããŸãã äžè¬ã«ããã·ã³åºæã®æäœã¯ãã®ããã«èŠããã¡ã¢ãªã®ç§»åãã«ãŒãã³ã®åŒã³åºããšæ»ããªã©ã®ããäžè¬çãªæŠå¿µã¯ããæœè±¡çã§ãã 詳现ã¯ã¢ãŒããã¯ãã£ã«äŸåããäžæ£ç¢ºãããforã³ããŸãïŒç¶æ³ã¯äžç¢ºãã§ãã
ã¢ã»ã³ãã©ãŒããã°ã©ã ã¯ããã®åæœè±¡åœä»€ã»ããã®èª¬æãè§£æãããªã³ã«ãŒã«è»¢éããããã®åœä»€ã«å€æããæ¹æ³ã§ãã
åçŽãªããã°ã©ã ã®åè§£
次ã®Goã³ãŒãïŒ
direct_topfunc_call.go ïŒãæ€èšããŠãã ããã
ïŒã³ã³ãã€ã©æä»€ã«æ³šæããŠãã ãã
//go:noinline
...泚æããŠãã ãããïŒ
ã¢ã»ã³ãã©ãŒã§ã³ãŒããã³ã³ãã€ã«ããŸãããïŒ
$ GOOS=linux GOARCH=amd64 go tool compile -S direct_topfunc_call.go 0x0000 TEXT "".add(SB), NOSPLIT, $0-16 0x0000 FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB) 0x0000 FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) 0x0000 MOVL "".b+12(SP), AX 0x0004 MOVL "".a+8(SP), CX 0x0008 ADDL CX, AX 0x000a MOVL AX, "".~r2+16(SP) 0x000e MOVB $1, "".~r3+20(SP) 0x0013 RET 0x0000 TEXT "".main(SB), $24-0 ;; ...omitted stack-split prologue... 0x000f SUBQ $24, SP 0x0013 MOVQ BP, 16(SP) 0x0018 LEAQ 16(SP), BP 0x001d FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) 0x001d FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) 0x001d MOVQ $137438953482, AX 0x0027 MOVQ AX, (SP) 0x002b PCDATA $0, $0 0x002b CALL "".add(SB) 0x0030 MOVQ 16(SP), BP 0x0035 ADDQ $24, SP 0x0039 RET ;; ...omitted stack-split epilogue...
ã³ã³ãã€ã©ã®åäœãçè§£ããããã«ã2ã€ã®é¢æ°ãè¡ããšã«é
眮ããŸããã
add
åæ
0x0000 TEXT "".add(SB), NOSPLIT, $0-16
0x0000
ïŒé¢æ°ã®éå§ã«å¯ŸããçŸåšã®åœä»€ã®ãªãã»ãããTEXT "".add
ïŒ TEXT
ãã£ã¬ã¯ãã£ãã¯ãã·ã³ãã«"".add
.text
ã»ã¯ã·ã§ã³ïŒã€ãŸããå®è¡å¯èœã³ãŒãïŒã®äžéš"".add
宣èšãããã£ã¬ã¯ãã£ãã«ç¶ãåœä»€ã颿°ã®æ¬äœã§ããããšãæå³ããŸãã
ãªã³ã¯äžã®ç©ºã®æåå""
ã¯ãçŸåšã®ããã±ãŒãžã®ååã«çœ®ãæããããŸããããšãã°ãæçµãã€ããªãžã®ãªã³ã¯åŸã®"".add
ã«ãªãmain.add
ã(SB)
ïŒ SB
ã¯ããéçããŒã¹ããã€ã³ã¿ãŒãã€ãŸãããã°ã©ã ã®ã¢ãã¬ã¹ç©ºéã®å
é ã®ã¢ãã¬ã¹ãå«ãä»®æ³ã¬ãžã¹ã¿ã§ãã
"".add(SB)
ã¯ããã£ã©ã¯ã¿ãŒãã¢ãã¬ã¹ç©ºéã®å
é ããäžå®ã®ãªãã»ããã§ã¢ãã¬ã¹ã«é
眮ãããŠããããšãéç¥ããŸãã ã€ãŸããããã¯ãã°ããŒãã«é¢æ°ã®ã·ã³ãã«ãæžã蟌ãŸãã絶察çãªçŽæ¥ã¢ãã¬ã¹ã§ãã ããã¯objdump
確èªããŸãïŒ
$ objdump -j .text -t direct_topfunc_call | grep 'main.add'
000000000044d980 g F .text 000000000000000f main.add
ãã¹ãŠã®ãŠãŒã¶ãŒæåã¯ãæ¬äŒŒã¬ãžã¹ã¿ãŒFPïŒåŒæ°ããã³ããŒã«ã«å€æ°ïŒããã³SBïŒã°ããŒãã«å€æ°ïŒã®ãªãã»ãããšããŠæžã蟌ãŸããŸãã SBæ¬äŒŒã¬ãžã¹ã¿ã¯ã¡ã¢ãªãœãŒã¹ãšèŠãªãããšãã§ãããããã·ã³ãã«foo(SB)
ã¯ã¡ã¢ãªå
ã®ã¢ãã¬ã¹ãšããŠã®ååfooã§ãã
NOSPLIT
ã¯ãçŸåšã®ã¹ã¿ãã¯ãæ¡å€§ããå¿
èŠããããã©ããã確èªããã¹ã¿ãã¯åå²ããªã¢ã³ãã«ãæ¿å
¥ããªãããã³ã³ãã€ã©ãŒã«æç€ºããŸãã
add
颿°ã®å Žåãã³ã³ãã€ã©ã¯ãã®ãã©ã°èªäœãèšå®ããŸããååã«ã¹ããŒãã§ããã add
ã¯ããŒã«ã«å€æ°ãšç¬èªã®ã¹ã¿ãã¯ãã¬ãŒã ããªããããçŸåšã®ã¹ã¿ãã¯ãåçŽã«æ¡åŒµããããšã¯ã§ããŸããã ã€ãŸããåŒã³åºãããšã«ãã§ãã¯ãå®è¡ãããããã»ããµãµã€ã¯ã«ãç¡é§ã«ãªããŸãã
"NOSPLIT"
ïŒã¹ã¿ãã¯ãåå²ããå¿
èŠãããå Žåãåæãã§ãã¯ãæ¿å
¥ããŸããã ã«ãŒãã³ã®ãã¬ãŒã ã¯ããããåŒã³åºããã®ãšåæ§ã«ãã¹ã¿ãã¯ã»ã°ã¡ã³ãã®å
é ã®ã¹ãã¢ã¹ããŒã¹ã«åãŸãå¿
èŠããããŸãã ã¹ã¿ãã¯åå²ã³ãŒãèªäœãªã©ã®ã«ãŒãã³ãä¿è·ããããã«äœ¿çšãããŸãã èšäºã®æåŸã§ããŽã«ãŒãã³ãšã¹ã¿ãã¯ããŒãã£ã·ã§ã³ã«ã€ããŠå°ã説æããŸãã
$0-16: $0
ã¡ã¢ãªã«å²ãåœãŠãããã¹ã¿ãã¯ãã¬ãŒã ã®ãµã€ãºïŒãã€ãåäœïŒã $16
ã¯ãåŒã³åºãå
ã«æž¡ãããåŒæ°ã®ãµã€ãºã§ãã
äžè¬ã«ãåŒæ°ã®ãµã€ãºã®åŸã«ã¯ããã€ãã¹èšå·ã§åºåãããåŒæ°ã®ãµã€ãºãç¶ããŸãïŒããã¯æžç®ã§ã¯ãªããæããªæ§æã§ãïŒã $24-8
ãã¬ãŒã ãµã€ãºã¯ã颿°ã24ãã€ãã®ãã¬ãŒã ãæã¡ãåŒã³åºãåŽã®ãã¬ãŒã ã«ãã8ãã€ãã®åŒæ°ã§åŒã³åºãããããšãæå³ããŸãã TEXT
NOSPLIT
ãæå®ãããŠããªãå ŽåãåŒæ°ã®ãµã€ãºãæå®ããå¿
èŠããããŸãã Goãããã¿ã€ãã䜿çšããã¢ã»ã³ãã©ãŒé¢æ°ã®å Žåã go vet
ã¯åŒæ°ã®ãµã€ãºãæ£ããããšã確èªããŸãã
0x0000 FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
0x0000 FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
FUNCDATA
ããã³
PCDATA
ã³ã³ãã€ã©ãŒã«ãã£ãŠæäŸãããã¬ããŒãžã³ã¬ã¯ã¿ãŒã®æ
å ±ãå«ãŸããŠããŸãã
ãŸã æ·±ãæãäžããŠã¯ãããŸãããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã調ã¹ãèšäºã§ããã«æ»ããŸãã
0x0000 MOVL "".b+12(SP), AX
0x0004 MOVL "".a+8(SP), CX
GoåŒã³åºãèŠçŽã¯ãåŒã³åºãå
ã®ã¹ã¿ãã¯ã®ãã¬ãŒã å
ã®äºåäºçŽã¹ããŒã¹ã䜿çšããŠããã¹ãŠã®åŒæ°ãã¹ã¿ãã¯ã«ããã·ã¥ããããã«æç€ºããŸãã åŒã³åºãå
ã«åŒæ°ãæž¡ããåŒã³åºãå
ã«å€ãè¿ãããšãã§ããããã«ãã¹ã¿ãã¯ãçž®å°ããã³å¢å ããããšã¯ãåŒã³åºãå
ã®è²¬ä»»ã§ãã
Goã³ã³ãã€ã©ãŒã¯PUSH / POPãã¡ããªãŒåœä»€ãçæããŸãããSPæ©åšã®ä»®æ³ã¹ã¿ãã¯ãã€ã³ã¿ãŒããã¯ãªã¡ã³ããŸãã¯ã€ã³ã¯ãªã¡ã³ãããããšã§ã¹ã¿ãã¯ãµã€ãºã倿ŽãããŸãïŒ
åé¡ïŒ21ã«ã€ããŠã®èª¬æãåç
§ããŠãã ãã
ïŒSPã¬ãžã¹ã¿ãŒã«ã€ã㊠ïŒã
SPæ¬äŒŒã¬ãžã¹ã¿ã¯ã颿°åŒã³åºãçšã«æºåãããããŒã«ã«ãã¬ãŒã 倿°ãšåŒæ°ãåç
§ããããã«äœ¿çšãããä»®æ³ã¹ã¿ãã¯ãã€ã³ã¿ãŒã§ãã ããŒã«ã«ã¹ã¿ãã¯ãã¬ãŒã ã®å
é ãæãããããªã³ã¯ã¯[-framesizeã0]ã®ç¯å²ã®è² ã®ãªãã»ããã䜿çšããå¿
èŠããããŸãïŒ x-8(SP)
ã y-4(SP)
ãªã©ã
å
¬åŒããã¥ã¡ã³ãã§ã¯ãããã¹ãŠã®ãŠãŒã¶ãŒæåã¯FPç䌌ã¬ãžã¹ã¿ãŒïŒåŒæ°ããã³ããŒã«ã«å€æ°ïŒã«å¯Ÿãããªãã»ãããšããŠæžã蟌ãŸããŸãããšæžãããŠããŸãããããã¯ãŠãŒã¶ãŒãäœæããã³ãŒãã«ã®ã¿åœãŠã¯ãŸããŸãã
ææ°ã®ã³ã³ãã€ã©ãšåæ§ã«ãçæãããã³ãŒãå
ã®GoããŒã«ãããã¯ãåžžã«ã¹ã¿ãã¯ãã€ã³ã¿ãŒããã®ãªãã»ããã䜿çšããŠåŒæ°ãšããŒã«ã«å€æ°ãçŽæ¥åç
§ããŸãã ããã«ãããã¹ã¿ãã¯ãã¬ãŒã ãã¬ãžã¹ã¿ã®å°ãªããã©ãããã©ãŒã ïŒx86ãªã©ïŒã§æ±çšã¬ãžã¹ã¿ãšããŠäœ¿çšã§ããŸãã
ãã®ãããªéå±ãªè©³çްã奜ããªå Žåã¯ãã
x86-64ã¹ã¿ãã¯ãã¬ãŒã å³ ããã芧ãã ããïŒåé¡ïŒ2ã®èª¬æãåç
§ããŠãã ããïŒãã¬ãŒã ãã€ã³ã¿ãŒïŒã
"".b+12(SP)
ããã³
"".a+8(SP)
ã¯ãã¹ã¿ãã¯ã®æäžéšãã12ããã³8ãã€ãã«ããã¢ãã¬ã¹ãæããŸãïŒèŠããŠãããŠãã ããïŒã¹ã¿ãã¯ãäžãã£ãŠãããŸãïŒïŒã
.a
ããã³
.b
ã¯ãåç
§ããå Žæã®ä»»æã®ãšã€ãªã¢ã¹ã§ãã
ã»ãã³ãã£ãã¯ãªæå³ã¯ãŸã£ãããããŸããããä»®æ³ã¬ãžã¹ã¿ãžã®çžå¯Ÿã¢ãã¬ã¹æå®ã䜿çšããå Žåã«äœ¿çšããããã«èŠå®ãããŠããŸãã 以äžã¯ãä»®æ³ãã¬ãŒã ãã€ã³ã¿ãŒã«é¢ããããã¥ã¡ã³ãã®èª¬æã§ãã
FPæ¬äŒŒã¬ãžã¹ã¿ã¯ã颿°ã®åŒæ°ãåç
§ããããã«äœ¿çšãããä»®æ³ãã¬ãŒã ãã€ã³ã¿ãŒã§ãã ã³ã³ãã€ã©ã¯ä»®æ³ãã¬ãŒã ãã€ã³ã¿ããµããŒãããã¹ã¿ãã¯äžã®åŒæ°ãæ¬äŒŒã¬ãžã¹ã¿ããã®ãªãã»ãããšããŠåç
§ããŸãã ãããã£ãŠã0ïŒFPïŒã¯é¢æ°ã®æåã®åŒæ°ã8ïŒFPïŒã¯2çªç®ïŒ64ããããã·ã³äžïŒãªã©ã§ãã ãã ãããã®æ¹æ³ã§é¢æ°ã®åŒæ°ãåç
§ããå Žåã¯ãæåã«ååãä»ããå¿
èŠããããŸããããšãã°ãfirst_arg + 0ïŒFPïŒããã³second_arg + 8ïŒFPïŒïŒããã§ããªãã»ãã-ãã¬ãŒã ãã€ã³ã¿ãŒãã-SBãšã¯ç°ãªããŸããæåïŒã ã¢ã»ã³ãã©ã¯ãã®èŠåã匷å¶çã«äœ¿çšããåçŽãª0ïŒFPïŒãš8ïŒFPïŒãæåŠããŸãã å®éã®ååã¯æå³çã«ã¯äžèŽããŸããããåŒæ°ã®ååãææžåããããã«äœ¿çšããå¿
èŠããããŸãã
æåŸã«ã泚æãã¹ãä»ã®2ã€ã®éèŠãªãã€ã³ãïŒ
- æåã®åŒæ°
a
ã¯0(SP)
ã§ã¯ãªã8(SP)
ã«ãããŸããããã¯ãåŒã³åºãåŽãçäŒŒé¢æ°CALL
ã䜿çšããŠãæ»ãã¢ãã¬ã¹ã0(SP)
CALL
ä¿åããããã§ãã - åŒæ°ã¯éã®é åºã§æž¡ãããŸãã ã€ãŸããæåã®åŒæ°ã¯ã¹ã¿ãã¯ã®æäžéšã«æãè¿ããªããŸãã
0x0008 ADDL CX, AX 0x000a MOVL AX, "".~r2+16(SP) 0x000e MOVB $1, "".~r3+20(SP)
ADDL
ã¯ã
AX
ãš
CX
ã«ãã2ã€ã®ãã³ã°ã¯ãŒãïŒ4ãã€ãå€ãªã©ïŒã远å ããçµæã¯
AX
æžã蟌ãŸããŸãã æ¬¡ã«ããã®çµæã¯
"".~r2+16(SP)
ã«ç§»åãã
"".~r2+16(SP)
ãã®ã¹ã¿ãã¯ã§ã¯ãåŒã³åºãå
ã以åã«å ŽæãäºçŽããããã§æ»ãå€ãæ¢ããŸãã ç¹°ãè¿ããŸããããã®å Žåã¯
"".~r2
ã«ã¯æå³çãªæå³ã¯ãããŸããã
Goãè€æ°ã®æ»ãå€ãåŠçããæ¹æ³ã瀺ãããã«ã
true
宿°ããŒã«å€ãè¿ã
true
ã ã¡ã«ããºã ã¯ãæåã®æ»ãå€ã®å ŽåãšãŸã£ããåãã§ã
SP
倿Žã«å¯Ÿå¿ããã®ã¯ãªãã»ããã®ã¿ã§ãã
0x0013 RET
RET
ç䌌åœä»€ã¯ãåŒã³åºãã«ãŒãã³ããçµæãæ£ããè¿ãããã«ãã¿ãŒã²ãããã©ãããã©ãŒã ã§äœ¿çšãããåŒã³åºãèŠçŽã«å¿
èŠãªåœä»€ãæ¿å
¥ããããã«ã¢ã»ã³ãã©Goã«æç€ºããŸãã ããã«ãããã³ãŒãã¯ç¢ºå®ã«
0(SP)
ãããªã¿ãŒã³ã¢ãã¬ã¹ããããïŒããã
0(SP)
ãããã«æ»ããŸãã
TEXTãããã¯ã®æåŸã®åœä»€ã¯ãäœããã®é·ç§»ã§ããå¿
èŠããããŸããããã¯éåžžïŒç䌌ïŒRETåœä»€ã§ãã ããã§ãªãå Žåããªã³ã«ã¯ãããèªäœãžã®é·ç§»ïŒjump-to-itselfïŒãæã€åœä»€ã远å ããŸãã TEXTãããã¯ã«ãã©ãŒã«ã¹ã«ãŒã¯ãããŸããã
äžåºŠã«å€ãã®æ§æãšã»ãã³ãã£ã¯ã¹ãåŠã¶å¿
èŠããããŸãã äžèšã®ã€ã³ã©ã€ã³ã®æŠèŠã¯æ¬¡ã®ãšããã§ãã
;; Declare global function symbol "".add (actually main.add once linked) ;; Do not insert stack-split preamble ;; 0 bytes of stack-frame, 16 bytes of arguments passed in ;; func add(a, b int32) (int32, bool) 0x0000 TEXT "".add(SB), NOSPLIT, $0-16 ;; ...omitted FUNCDATA stuff... 0x0000 MOVL "".b+12(SP), AX ;; move second Long-word (4B) argument from caller's stack-frame into AX 0x0004 MOVL "".a+8(SP), CX ;; move first Long-word (4B) argument from caller's stack-frame into CX 0x0008 ADDL CX, AX ;; compute AX=CX+AX 0x000a MOVL AX, "".~r2+16(SP) ;; move addition result (AX) into caller's stack-frame 0x000e MOVB $1, "".~r3+20(SP) ;; move `true` boolean (constant) into caller's stack-frame 0x0013 RET ;; jump to return address stored at 0(SP)
ãããŠã
main.add
ã¯
main.add
å®è¡å®äºåŸã®ã¹ã¿ãã¯ã®å
容ã®èŠèŠç衚çŸã§ãïŒ
| +-------------------------+ <-- 32(SP) | | | G | | | R | | | O | | main.main's saved | W | | frame-pointer (BP) | S | |-------------------------| <-- 24(SP) | | [alignment] | D | | "".~r3 (bool) = 1/true | <-- 21(SP) O | |-------------------------| <-- 20(SP) W | | | N | | "".~r2 (int32) = 42 | W | |-------------------------| <-- 16(SP) A | | | R | | "".b (int32) = 32 | D | |-------------------------| <-- 12(SP) S | | | | | "".a (int32) = 10 | | |-------------------------| <-- 8(SP) | | | | | | | | | \ | / | return address to | \|/ | main.main + 0x30 | - +-------------------------+ <-- 0(SP) (TOP OF STACK) (diagram made with https://textik.com)
main
åæãã
èšäºãèªã¿é²ããå¿
èŠããªãããã«ã
main
æ©èœãã©ã®ããã«èŠããããæãåºãããŠãã ããã
0x0000 TEXT "".main(SB), $24-0 ;; ...omitted stack-split prologue... 0x000f SUBQ $24, SP 0x0013 MOVQ BP, 16(SP) 0x0018 LEAQ 16(SP), BP ;; ...omitted FUNCDATA stuff... 0x001d MOVQ $137438953482, AX 0x0027 MOVQ AX, (SP) ;; ...omitted PCDATA stuff... 0x002b CALL "".add(SB) 0x0030 MOVQ 16(SP), BP 0x0035 ADDQ $24, SP 0x0039 RET ;; ...omitted stack-split epilogue... 0x0000 TEXT "".main(SB), $24-0
æ°ãããã®ã¯ãããŸããïŒ
"".main
ïŒäžåºŠmain.main
ïŒã¯ã .text
ã»ã¯ã·ã§ã³ã®ã°ããŒãã«é¢æ°ã®ã·ã³ãã«ã§ããããã®ã¢ãã¬ã¹ã¯ã¢ãã¬ã¹ç©ºéã®å
é ããã®äžå®ã®ãªãã»ããã§ãã- ãã®ã³ãŒãã¯ã24ãã€ãã®ã¹ã¿ãã¯ãã¬ãŒã ãã¡ã¢ãªã«é
眮ããåŒæ°ãåãåãããå€ãè¿ããŸããã
0x000f SUBQ $24, SP
0x0013 MOVQ BP, 16(SP)
0x0018 LEAQ 16(SP), BP
äžèšã®ããã«ãGoã®åŒã³åºãèŠçŽã§ã¯ããã¹ãŠã®åŒæ°ãã¹ã¿ãã¯ã«æž¡ãå¿
èŠããããŸãã
åŒã³åºãå
SUBQ
ã¯ãä»®æ³ã¹ã¿ãã¯ãã€ã³ã¿ããã¯ãªã¡ã³ãããããšã«ãããã¹ã¿ãã¯ãã¬ãŒã ã24ãã€ãå¢ãããŸãïŒ
ã¹ã¿ãã¯ã倧ãããªãããšãå¿ããªãã§ãã ããããã®å Žåã SUBQ
ã¯ã¹ã¿ãã¯ãã¬ãŒã ãå¢ãããŸã ïŒã ãããã®24ãã€ãã®æ§æïŒ
- 8ãã€ãïŒ
16(SP)-24(SP)
ïŒã¯ãBPãã¬ãŒã ãã€ã³ã¿ãŒïŒ çŸåšïŒ ïŒã®çŸåšã®å€ãæ ŒçŽããããã«äœ¿çšãããŸããã¹ã¿ãã¯ã®ææ ŒïŒã¹ã¿ãã¯ã®å·»ãæ»ãïŒãšãããã°ã®ç°¡çŽ åã®ããã«ã - 1 + 3ãã€ãïŒ
12(SP)-16(SP)
ïŒã¯ã2çªç®ã®æ»ãå€ïŒ bool
ïŒã«å ããŠãamd64ã§å¿
èŠãª3ãã€ãã®ã¢ã©ã€ã¡ã³ãçšã«äºçŽãããŠããŸãã - 4ãã€ãïŒ
8(SP)-12(SP)
ïŒã¯ãæåã®æ»ãå€ïŒ int32
ïŒçšã«äºçŽãããŠããŸãã - 4ãã€ãïŒ
4(SP)-8(SP)
ïŒã¯ãåŒæ°bïŒ int32
ïŒã®å€çšã«äºçŽãããŠããŸãã - 4ãã€ãïŒ
0(SP)-4(SP)
ïŒã¯ãåŒæ°aïŒ int32
ïŒã®å€çšã«äºçŽãããŠããŸãã
æåŸã«ãã¹ã¿ãã¯ãå¢ãããåŸã
LEAQ
ã¯ãã¬ãŒã ãã€ã³ã¿ãŒã®æ°ããã¢ãã¬ã¹ãèšç®ããããã
BP
æ ŒçŽããŸãã
0x001d MOVQ $137438953482, AX 0x0027 MOVQ AX, (SP)
åŒã³åºãå
ã¯ãåŒã³åºãå
ã®åŒæ°ãã¯ã¯ããã¯ãŒãïŒ8ãã€ãå€ïŒãšããŠåãåããå±éããã°ããã®ã¹ã¿ãã¯ã®äžçªäžã«çœ®ããŸãã
äžèŠãããšã©ã³ãã ãªãŽãã®ããã«èŠããŸãããå®éã«ã¯
137438953482
ã¯4ãã€ãå€
10
ãš
32
ã«å¯Ÿå¿ããŠããããããã¯1ã€ã®8ãã€ãå€ã«æ¥ç¶ãããŠããŸãã
$ echo 'obase=2;137438953482' | bc 10000000000000000000000000000000001010 \____/\______________________________/ 32 10 0x002b CALL "".add(SB)
CALL
ããéçããŒã¹ãã€ã³ã¿ãŒã«å¯Ÿãããªãã»ãããšããŠ
add
颿°ã«é©çšããŸãã ã€ãŸããçŽæ¥ã¢ãã¬ã¹ãžã®çŽæ¥é·ç§»ã§ãã
CALL
ã¯ãã¹ã¿ãã¯ã®å
é ã«æ»ãã¢ãã¬ã¹ïŒ8ãã€ãå€ïŒãé
眮ããããšã«æ³šæããŠãã ããã ãããã£ãŠã
add
颿°å
ãã
SP
ãžã®ååç
§ã¯8ãã€ãã·ãããããŸãïŒ ããšãã°ã
"".a
ã¯
0(SP)
ã§ã¯ãªã
8(SP)
ãŸãã
0x0030 MOVQ 16(SP), BP 0x0035 ADDQ $24, SP 0x0039 RET
æåŸã«ãæã
ïŒ
- ãã¬ãŒã ãã€ã³ã¿ãŒã1ã€ã®ã¹ã¿ãã¯ãã€ã³ã¿ãŒã«å·»ãæ»ããŸãïŒã€ãŸãã1ã¬ãã«ãããŠã³ãããŸãïŒã
- ã¹ã¿ãã¯ã24ãã€ãæžãããŠã以åã«å æããŠããã¹ããŒã¹ãè¿ããŸãã
- ã¢ã»ã³ãã©Goã«æ»ãã«ãŒãã³ãæ¿å
¥ããããã«äŸé ŒããŸãã
ãŽã«ãŒãã³ãã¹ã¿ãã¯ãããŒãã£ã·ã§ã³ã«é¢ããããã€ãã®èšè
ä»ã¯ãŽã«ãŒãã³ã®ã®ãã«ãæ±ãæã§ãå Žæã§ããããŸããããã¢ã»ã³ãã©ãŒã«é£ã³èŸŒã¿å§ããå Žåãã¹ã¿ãã¯ã®ç®¡çã«é¢ããæç€ºã«ããã«æ
£ããå¿
èŠããããŸãã
ãããã®ãã¿ãŒã³ãè¿
éã«èªèããäžè¬ã«ããããäœãã©ã®ããã«è¡ãããçè§£ã§ããå¿
èŠããããŸãã
ã¹ã¿ãã¯
Goããã°ã©ã ã®ãŽã«ãŒãã³ã®éã¯æ±ºå®ãããŠããããå®éã«ã¯æ°çŸäžã«éããå¯èœæ§ãããããã䜿çšå¯èœãªã¡ã¢ãªããã¹ãŠæ¶è²»ããªãããã«ããã«ã¯ãå®è¡æã«ãŽã«ãŒãã³ã«ã¹ã¿ãã¯ãå²ãåœãŠãä¿å®çãªæ¹æ³ã«åŸãå¿
èŠããããŸãã
ãããã£ãŠãæ°ãããŽã«ãŒãã³ã¯ãããããå®è¡æã«æåã«å°ããª2 KBã¹ã¿ãã¯ãååŸããŸãïŒå®éãããŒãäžã«ãããŸãïŒã
å®è¡äžãgoroutinã¯ã¹ã¿ãã¯ã®åæã¹ããŒã¹ãã倧ãããªãããšããããŸãïŒã€ãŸããã¹ã¿ãã¯ãªãŒããŒãããŒãçºçããŸãïŒã ãããé²ãããã«ãã©ã³ã¿ã€ã ç°å¢ã¯ãã¹ã¿ãã¯ãæºãããšãã«ãå€ãã¹ã¿ãã¯ã®2åã®ãµã€ãºã®æ°ããã¹ã¿ãã¯ãå²ãåœãŠããã®å
å®¹ãæ°ããã¹ã¿ãã¯ã«ã³ããŒãããŸãã
ãã®ããã»ã¹ã¯ã¹ã¿ãã¯ã¹ããªãããšåŒã°ãããŽã«ãŒãã³ã«åçãªã¹ã¿ãã¯ã¡ã«ããºã ãæäŸããŸãã
éšé
ã¹ã¿ãã¯åé¢ã¡ã«ããºã ãæ©èœããããã«ãã³ã³ãã€ã©ãŒã¯ãã¹ã¿ãã¯ããªãŒããŒãããŒãããå¯èœæ§ã®ããå颿°ã®å
é ãšæ«å°Ÿã«æ°ããåœä»€ãæ¿å
¥ããŸãã
äžèŠãªãªãŒããŒããããåé¿ããããã«ãã¹ã¿ãã¯ãè¶
ããå¯èœæ§ãäœã颿°ã«ã¯NOSPLITã®ããŒã¯ãä»ããããŸããããã¯ããã§ãã¯ãæ¿å
¥ããªãããã³ã³ãã€ã©ãŒã«æç€ºããŸãã
ã¡ã€ã³é¢æ°ãèŠãŠã¿ãŸãããããä»åã¯ã¹ã¿ãã¯åå²ããªã¢ã³ãã«ãåé€ããã«ïŒ
0x0000 TEXT "".main(SB), $24-0 ;; stack-split prologue 0x0000 MOVQ (TLS), CX 0x0009 CMPQ SP, 16(CX) 0x000d JLS 58 0x000f SUBQ $24, SP 0x0013 MOVQ BP, 16(SP) 0x0018 LEAQ 16(SP), BP ;; ...omitted FUNCDATA stuff... 0x001d MOVQ $137438953482, AX 0x0027 MOVQ AX, (SP) ;; ...omitted PCDATA stuff... 0x002b CALL "".add(SB) 0x0030 MOVQ 16(SP), BP 0x0035 ADDQ $24, SP 0x0039 RET ;; stack-split epilogue 0x003a NOP ;; ...omitted PCDATA stuff... 0x003a CALL runtime.morestack_noctxt(SB) 0x003f JMP 0
ã芧ã®ãšãããããªã¢ã³ãã«ã¯ããããŒã°ãšãšãããŒã°ã«åãããŠããŸãã
- ããããŒã°ã§ã¯ããŽã«ãŒãã³ã«å²ãåœãŠãããã¹ããŒã¹ããªãŒããŒãããŒããŠãããã©ããããã§ãã¯ããããªãŒããŒãããŒããŠããå Žåãå®è¡ã¯ãšãããŒã°ã«é²ã¿ãŸãã
- ãšãããŒã°ã¯ã¹ã¿ãã¯æ¡åŒµã¡ã«ããºã ãéå§ããããããŒã°ã«æ»ããŸãã
ãã£ãŒãããã¯ã«ãŒããçºçããã飢vingããŽã«ãŒãã³ã«ååã«å€§ããªã¹ã¿ãã¯ãå²ãåœãŠããããŸã§æ©èœããŸãã
ããããŒã° 0x0000 MOVQ (TLS), CX ;; store current *g in CX 0x0009 CMPQ SP, 16(CX) ;; compare SP and g.stackguard0 0x000d JLS 58 ;; jumps to 0x3a if SP <= g.stackguard0
TLS
ã¯ãã©ã³ã¿ã€ã ç°å¢ã«ãã£ãŠç¶æãããä»®æ³ã¬ãžã¹ã¿ã§ãããçŸåšã®
g
ãã€ãŸããŽã«ãŒãã³ã®ç¶æ
å
šäœãç£èŠããããŒã¿æ§é ãžã®ãã€ã³ã¿ãŒãå«ã¿ãŸãã
ã©ã³ã¿ã€ã ãœãŒã¹ã³ãŒãã®
g
ã®å®çŸ©ãèŠãŠã¿ãŸãããã
type g struct { stack stack
16(CX)
ã¯ãã©ã³ã¿ã€ã ç°å¢ã§ãµããŒãããããããå€ã§ãã
g.stackguard0
ã«å¯Ÿå¿ããŸãã 圌女ã¯ãã®å€ãã¹ã¿ãã¯ãã€ã³ã¿ãŒãšæ¯èŒãããŽã«ãŒãã³ãã¹ã¿ãã¯äžè¶³ã«è¿ã¥ããŠãããã©ããã調ã¹ãŸãã ã€ãŸããããããŒã°ã¯ãçŸåšã®
SP
å€ã
stackguard0
ïŒæ£ç¢ºã«ã¯å€§ããïŒãã©ããã確èªããå¿
èŠã«å¿ããŠãšãããŒã°ã«é²ã¿ãŸãã
ãšãããŒã° 0x003a NOP 0x003a CALL runtime.morestack_noctxt(SB) 0x003f JMP 0
ãšãããŒã°ã®æ¬äœã¯åçŽã§ãïŒã©ã³ã¿ã€ã äžã«åŒã³åºãããã¹ã¿ãã¯ãå¢ããããã®ãã¹ãŠã®äœæ¥ãè¡ã£ãåŸã颿°ã®æåã®åœä»€ïŒã€ãŸããããããŒã°ïŒã«æ»ããŸãã
NOP
åœä»€ã¯
CALL
åã«ãããããããããŒã°ã¯
CALL
ã«çŽæ¥ç§»åããŸããã äžéšã®ãã©ãããã©ãŒã ã§ã¯ãããã«ããæªåœ±é¿ãçããå¯èœæ§ããããŸãã ãã®ãããã³ãŒã«èªäœã®çŽåã«ãéåžžã¯noopåœä»€ãæ¿å
¥ãã
NOP
å°éããŸãïŒ
ãåé¡4ïŒã³ãŒã«åã®nopãæ®µèœã®èª¬æãåç
§ããŠãã ããïŒã
埮åŠãªãã€ãã¹
æ°·å±±ã®äžè§ã ãã調ã¹ãŸããã ã¹ã¿ãã¯ã®æé·ã®å
éšã¡ã«ããºã ã«ã¯ããã«å€ãã®ãã¥ã¢ã³ã¹ããããŸããããã»ã¹ã¯éåžžã«è€éã§ã詳现ãªã¬ãã¥ãŒã®ããã«å¥ã®èšäºãå¿
èŠã§ãã
ãããã«
次ã®èšäºã§Goããã€ã¹ã«æ²¡é ãããšãGoã¢ã»ã³ãã©ãŒã¯ãå
éšã¡ã«ããºã ãšäžèŠããŸãæããã§ã¯ãªããã®ãšã®é¢ä¿ãçè§£ããããã®æãéèŠãªããŒã«ã®1ã€ã«ãªããŸãã
åç
§è³æ