Hacker News new | ask | show | jobs
by acqq 2230 days ago
Just looking from afar, I don't have time to analyze every other claim, but this one:

> Both C++ and Rust have generated identical assembly listings; both have added push rbx for the sake of stack alignment. Q.E.D.

seems to be completely wrong: a decent compiler is able to align the stack without "touching" it. For the variables inside of the function to be pushed to the aligned stack position, only different offsets have to be calculated. For the stack itself to get to be aligned, only the register has to be updated, surely nothing has to be pushed.

So something else must have been happening there, and I don't have time to analyze what, but I'm sure push is surely not necessary for alignment alone.

3 comments

Counterintuitively, on some x86 architectures, push ¿is/can be? faster than decreasing the stack pointer’s value because the CPU uses dedicated hardware to speed up subroutine calls (https://stackoverflow.com/a/36633556)
It may just be for alignment. A push may be just (having a specific case in the CPU) as fast as updating the SP.
You are correct, it has nothing to do with alignment. rbx is a callee-saved register, so the callee saves it.
Do you mean thar rax is caller-saved?
rax is indeed caller-saved, but I was referring to rbx. In this code:

    int bar(int a, int b) {
       int z = a * b;
       foo();
       return z;
    }
https://godbolt.org/z/a8Y35r

Where to put `z`? It has to be someplace where `foo` won't clobber it, like a callee-saved register - in this case ebx.

But now `bar` is responsible for saving the value of ebx for its caller. That explains the push and pop.

Alignment is unrelated; this is just about calling conventions.