The section describing how a function call is made appears to be slightly incorrect.
The return value of the `add` function, in most ABI definitions, would be stored in a register. After that, the `main` function may then copy that value to its own space it has reserved on the stack.
This is at odds with the description in the article, which seems to describe `add` passing its return value to `main` via the stack.
(This is assuming no optimizations - all this would most likely be inlined anyway, with no function call.)