Common x86 Calling Conventions
jlospinoso.github.io
jlospinoso.github.io
When I saw the following, I stopped reading:
MultiplyEaxByTwo:
shl eax,2
ret
"shl eax, 2" means bit shift left eax by two, or "eax << 2". Also, while the end result is same as with "shl" [1], "sal" [2] should be used for idiomatic [3] assembler:Fixed:
CorrectMultiplyEaxByTwo:
sal eax, 1
ret
[1]: "shl", shift logical left[2]: "sal", shift arithmetic left
[3]: http://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate#A...
Also, "sal" and "shl" perform the exact same operation with the exact same side-effects. Some sources seem to hint that "sal" is the one going out of fashion - https://code.google.com/p/corkami/wiki/x86oddities#sal and http://stackoverflow.com/a/8373438/2412419
- shift right and insert 0 ("logical right")
- shift right and insert sign bit ("arithmetic right")
- shift left and insert 0 ("logical left")
- shift left and insert... 0 ("arithmetic left") **
My guess is that it causes the hardware to attempt to sign-extend and shift left, but the latter means the former doesn't have any effect.The Z80 has a similar gap in the encoding but rather more unusual undocumented behaviour here, where it would shift left and insert a 1 in the lowest bit.
It also mentions very little (i.e. not at all) about callee/caller-saved registers, which is a very important part of a calling convention.
There's another "WTF" moment in the code too:
xor eax,eax
add eax,[esp+4]
add eax,[esp+8]
add eax,[esp+12]
I was somewhat confused at the diagrams with "low memory" at the top and "high memory" at the bottom...The bad news is that it's from '99 but, as far as the foundations go, I can't imagine linkers back then were that different.