Mini Fridge
Mini Fridge

Reputation: 939

How does inline (x86) assembly affect the program flow?

I'm trying to understand how such snippets are invoked during run time:

__asm{
    PUSH ES
    MOV CX,0
    //... More x86 assembly
};

Won't tweaking the registers corrupt the program flow execution?

For example: If CX above holds some value, wouldn't this mean that this register value will no longer be valid?

Does the compiler take care of these dependencies or does the execution of the snippet happens under special circumstances?

On which compilers the usage of inline assembly is not transparent?

Upvotes: 2

Views: 192

Answers (2)

BrunoLevy
BrunoLevy

Reputation: 2623

There are some additional flags that can be passed to the inline assembly code. One of them is the "clobber list", that indicates to the C/C++ compiler the list of registers that will be modified by the bloc of assembly code.

Note that the way to specify these additional flags is dependent on the compiler (it is completely different in Microsoft Visual C++, GCC etc...)

For GCC, see for instance:

https://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.3

Upvotes: 1

oo_miguel
oo_miguel

Reputation: 2379

GCC

In GCC you have to specify the affected registers explicitly to prevent corruption of the exectution flow:

asm [volatile] ( AssemblerTemplate
                  : OutputOperands
                  [ : InputOperands
                  [ : Clobbers ] ])

While the compiler is aware of changes to entries listed in the output operands, the inline asm code may modify more than just the outputs.[...] calculations may require additional registers, [...] list them in the clobber list.

Please use the "memory" clobber argument if your code performs reads or writes to other items, than already listed.

The "memory" clobber tells the compiler that the assembly code performs memory reads or writes to items other than those listed in the input and output operands

Reference: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

MSVC

In MSVC on the other hand, you don't need to preserve the general purpose registers:

When using __asm to write assembly language in C/C++ functions, you don't need to preserve the EAX, EBX, ECX, EDX, ESI, or EDI registers. [...]

You should preserve other registers you use (such as DS, SS, SP, BP, and flags registers) for the scope of the __asm block. You should preserve the ESP and EBP registers unless you have some reason to change them.

Reference: https://msdn.microsoft.com/en-us/library/k1a8ss06.aspx


EDITS: changed should to have to for gcc and added note about the "memory" clobber argument, follwing Olafs suggestions.

Upvotes: 3

Related Questions