I am trying to compile the below code with ICC 2018:
__asm {
mov ebx, xx ;xx address to registers
}
where xx is of type int16. This is the first instruction inside my function.
I get the below warning with the above assembly code: warning #13212: Reference to ebx in function requiring stack alignment
Surprisingly, when I replaced ebx with eax or esi, I saw the warning go away. I am not able to understand why I am seeing the issue only with ebx, as far as I know, both ebx and eax has same architecture(32 bit registers).
Also, I didn't see the warning when I compiled the same code with ICC 2013.
Can anyone help me resolve this warning?
Thanks!
The compiler on the platform of choice (ICC as it mimics MSVC's behavior) uses EBX to save the original stack pointer value if additional alignment is required. Therefore you cannot overwrite it safely. The program's behavior would become undefined. The compiler warning just tells you about that.
To help with save/restore of all registers affected by assembly blocks, an extended syntax with so called clobber lists is recommended. Your example uses MSVC-style __asm{...}
syntax. In MSVC-style syntax, the compiler detects what registers you touch and saves/restores them for you.
ICC also supports GCC-like notation for extended asm with clobber lists: asm("...":::)
. It also supports simpler GCC asm("...")
without the clobber list part. See this question for more details (thanks Peter Cordes for the link and explanation).
Documentation that I found useful when I was learning to use clobber lists (I actually use it all the time because it is impossible to remember its rather human-unfriendly syntax):
The simple inline assembly blocks without clobber lists can be safely used only in the following situations:
INT3
, HLT
, WRMSR
etc instructions which either touch no registers or affect only system registers which the compiler do not use. However, the majority of such instructions are privileged and cannot be used in user applications. One can also read all available registers provided there are no side effects of such reads.register asm
statement (do not remember if the same trick works with other compilers). You can thus declare that a variable is bound to a certain register. Be aware that such technique reduces number of registers available to compiler for its register allocation phase, and that will degrade quality of code it generates. Ask for too many registers, and the compiler will be helpless and refuse to work. Similarly, one cannot ask for registers with a dedicated role to be taken away from a compiler, such as stack pointer or program counter.That said, the extended asm
syntax with clobber lists provides a nice alternative. It turns an asm
section from a black box to something of an inline internal "function" that declares its own inputs, outputs and resources it overwrites which are shared with the outer function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With