On Mon, Dec 17, 2012 at 7:10 AM, bryanturley <
bryan...@gmail.com> wrote:
> Also I have no idea what the calling convention's are or what the numbers at
> the end of this line mean
> TEXT ·FastSum2Uint8(SB),7,$0 // 7??? $0 ??? !?!?!?!
The caller is responsible for adjusting the stack pointer, and copying
arguments to and return values from the stack. Consider this program:
$ cat main.go
package main
func f(x, y int) int {
return x+y
}
var z int
func main() {
z = f(3, 4)
}
The 6g disassembly (-S) with inlining disabled (-l) is:
$ go tool 6g -S -l -o /dev/null main.go
--- prog list "f" ---
0000 (main.go:3) TEXT f+0(SB),$0-24
0001 (main.go:4) MOVQ x+0(FP),BX
0002 (main.go:4) MOVQ y+8(FP),BP
0003 (main.go:4) ADDQ BP,BX
0004 (main.go:4) MOVQ BX,.noname+16(FP)
0005 (main.go:4) RET ,
--- prog list "main" ---
0006 (main.go:9) TEXT main+0(SB),$24-0
0007 (main.go:10) MOVQ $3,(SP)
0008 (main.go:10) MOVQ $4,8(SP)
0009 (main.go:10) CALL ,f+0(SB)
0010 (main.go:10) MOVQ 16(SP),AX
0011 (main.go:10) MOVQ AX,z+0(SB)
0012 (main.go:11) RET ,
CALL is a pseudo-instruction that the linker expands to also manage
the split stacks (and call runtime.morestack if necessary). The true
disassembly is:
$ go build -gcflags '-l' main.go
$ objdump -d main
0000000000400c00 <main.f>:
400c00: 48 8b 5c 24 08 mov 0x8(%rsp),%rbx
400c05: 48 8b 6c 24 10 mov 0x10(%rsp),%rbp
400c0a: 48 01 eb add %rbp,%rbx
400c0d: 48 89 5c 24 18 mov %rbx,0x18(%rsp)
400c12: c3 retq
...
0000000000400c20 <main.main>:
400c20: 64 48 8b 0c 25 f0 ff mov %fs:0xfffffffffffffff0,%rcx
400c27: ff ff
400c29: 48 3b 21 cmp (%rcx),%rsp
400c2c: 77 05 ja 400c33 <main.main+0x13>
400c2e: e8 ed 16 01 00 callq 412320 <runtime.morestack00>
400c33: 48 83 ec 18 sub $0x18,%rsp
400c37: 48 c7 04 24 03 00 00 movq $0x3,(%rsp)
400c3e: 00
400c3f: 48 c7 44 24 08 04 00 movq $0x4,0x8(%rsp)
400c46: 00 00
400c48: e8 b3 ff ff ff callq 400c00 <main.f>
400c4d: 48 8b 44 24 10 mov 0x10(%rsp),%rax
400c52: 48 89 04 25 40 9e 45 mov %rax,0x459e40
400c59: 00
400c5a: 48 83 c4 18 add $0x18,%rsp
400c5e: c3 retq
...
In general...
TEXT f(SB),$8-16 means that on entry to the function the linker should
insert the allocation (splitting if necessary) of an 8-byte stack
frame. That is, the function can safely scribble on bytes 0(SB)
through 7(SB). The -16 means that there are 16 bytes of arguments, at
bytes 0(FP) through 15(FP), and if the stack gets split by the code
the linker inserts, those 16 bytes need to be copied over too.
TEXT f(SB),7,$x means that the linker should never split the stack for
f: instead it should assume that the frame can be grown by x bytes
without a check. (The linker also verifies this claim at link time; x
must be small, and the chain of called functions can't add up to more
than 128 bytes.) Because there's no stack split there is no need for
the -16. The function can still refer to its arguments (they're in the
stack frame of the caller), unconditionally, since there is no chance
of a stack split.
TEXT f(SB),7,$0 means that the function needs no extra space for
itself and does not want the stack split. Like above, because there's
no stack split there's no declaration of how many argument bytes there
are.
The flag bits in the 7 are defined in src/cmd/6l/6.out.h. The important one is
#define NOSPLIT (1<<2)
See also src/pkg/runtime/stack.h.