golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.72k stars 17.5k forks source link

doc: document assembly calling convention #16922

Open randall77 opened 8 years ago

randall77 commented 8 years ago

We should probably specify the Go calling convention in doc/asm.html, at least to a degree.

Might be especially useful as a reference when we get around to changing it.

@cherrymui @dr2chase @nigeltao

josharian commented 8 years ago

For future reference, the golang-dev thread that spawned this: https://groups.google.com/forum/m/#!topic/golang-dev/8RywCWxHVYA

cc @prattmic — this might be a good place to add questions to be answered by the doc

There's a useful stack layout ascii art diagram in runtime/stack.go that should go in this doc.

prattmic commented 8 years ago

The parts of the calling convention I have most recently struggled with doing the RISC-V port are what the exact stack layout looks like. There is reserved space for params and autos, and on some arches Ctxt.FixedFrameSize() reserves space for the return address. Does that space go between the params and autos? Where should the SP point on function entry? I still haven't quite figured out the answer to these questions.

Some of these questions have more to do with the handling of CALL and TEXT in the assembler, and shouldn't affect programmers writing assembly.

mundaym commented 8 years ago

@prattmic I did a presentation on Go's assembly language at Golang UK. In it there are some diagrams of the stack layout which you might find useful.

GoFunctionsInAssembly.pdf

4ad commented 8 years ago

@prattmic

Does that space go between the params and autos?

Which space? The space for the return address? The return address is saved at a known fixed offset from the stack pointer, usually 0, but 120 on sparc64. It is below the arguments passed to the next function.

If you don't put at at a fixed address, you can't have variadic functions (not an issue for Go, but in general). For Go however, it would be much difficult to implement context save and restore (e.g. for the select statement).

Where should the SP point on function entry?

On link register architectures, it should point to the previous stack frame. The callee modifies the stack pointer. But perhaps you mean something else, because this is true for pretty much any ABI on link register architectures. Where else could the stack pointer point to?

Perhaps you are referring to the virtual SP register in the go assembly? Perhaps you are wondering how to set Spadj? What exactly do you mean?

prattmic commented 8 years ago

@mundaym Thanks for those slides! The diagram on slide 21 is exactly what I needed. (I was conflating the parent return address and return address)

bcmills commented 7 years ago

I would appreciate a reference too. I'm doing a lot of debugging of cgo programs lately (including various parts of the runtime, and especially chaining of signal handlers across languages), and it would be especially useful to have some documentation regarding the interaction of frame pointers (#15840) and callee-saved registers.

rsc commented 7 years ago

@bcmills There are no callee-saved registers.

bcmills commented 7 years ago

Presumably the frame pointer is callee-saved when it's enabled, though. I'm also finding that the details of stack parameter alignment are a bit fuzzy in the documentation.

The presentation that @mundaym linked has been invaluable to me, but proper, discoverable documentation would really be helpful.

bcmills commented 7 years ago

One more bit of calling-convention documentation that would be useful to have: how are function closures passed?

It looks like closures are stored as instances of the funcval struct, with the pointer to the funcval passed to the closure in the DX register (on amd64). Is that correct?

randall77 commented 7 years ago

@bcmills That is correct. s/passed to the closure/passed to the function/

mcandre commented 6 years ago

I just want to know why the center dot, a rather inconvenient character on most QWERTY keyboards, was chosen as an important part of Go assembler syntax :P

knz commented 6 years ago

I have written a detailed analysis of the x86-64 calling convention here: http://science.raphael.poss.name/go-calling-convention-x86-64.html