New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: document assembly calling convention #16922

Open
randall77 opened this Issue Aug 30, 2016 · 12 comments

Comments

Projects
None yet
@randall77
Contributor

randall77 commented Aug 30, 2016

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

@randall77 randall77 added this to the Go1.8 milestone Aug 30, 2016

@josharian

This comment has been minimized.

Show comment
Hide comment
@josharian

josharian Aug 30, 2016

Contributor

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.

Contributor

josharian commented Aug 30, 2016

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

This comment has been minimized.

Show comment
Hide comment
@prattmic

prattmic Aug 31, 2016

Contributor

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.

Contributor

prattmic commented Aug 31, 2016

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

This comment has been minimized.

Show comment
Hide comment
@mundaym

mundaym Aug 31, 2016

Member

@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

Member

mundaym commented Aug 31, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@4ad

4ad Sep 1, 2016

Member

@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?

Member

4ad commented Sep 1, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@prattmic

prattmic Sep 4, 2016

Contributor

@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)

Contributor

prattmic commented Sep 4, 2016

@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)

@quentinmit quentinmit added the NeedsFix label Oct 7, 2016

@bcmills

This comment has been minimized.

Show comment
Hide comment
@bcmills

bcmills Oct 28, 2016

Member

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.

Member

bcmills commented Oct 28, 2016

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

This comment has been minimized.

Show comment
Hide comment
@rsc

rsc Nov 11, 2016

Contributor

@bcmills There are no callee-saved registers.

Contributor

rsc commented Nov 11, 2016

@bcmills There are no callee-saved registers.

@rsc rsc modified the milestones: Go1.9, Go1.8 Nov 11, 2016

@bcmills

This comment has been minimized.

Show comment
Hide comment
@bcmills

bcmills Nov 11, 2016

Member

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.

Member

bcmills commented Nov 11, 2016

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

This comment has been minimized.

Show comment
Hide comment
@bcmills

bcmills Nov 14, 2016

Member

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?

Member

bcmills commented Nov 14, 2016

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

This comment has been minimized.

Show comment
Hide comment
@randall77

randall77 Nov 14, 2016

Contributor

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

Contributor

randall77 commented Nov 14, 2016

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

@mcandre

This comment has been minimized.

Show comment
Hide comment
@mcandre

mcandre Jul 11, 2018

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

mcandre commented Jul 11, 2018

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

This comment has been minimized.

Show comment
Hide comment
@knz

knz Jul 30, 2018

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

knz commented Jul 30, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment