// @topic W120111 Inline assembly demo
// @brief Demonstrates MSVC++ <tt>__asm</tt> keyword

// inline_assembly_demo.cpp

#include <iostream>

using std::cout;

void foo()
{
    //----------------------------------------------------------------
    // We found that C library function strlen is written in assembly
    //----------------------------------------------------------------
    // C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\intel\strlen.asm
    strlen( "hello" );


    //----------------------------------------------------------------
    // A few tricks with inline assember
    //----------------------------------------------------------------
    int location = 0;         // this is local integer variable
mylabel:                      // this is a program label

    __asm {                   ;; begin inline assembly
        push eax              ;; preserve EAX
        lea  eax, mylabel     ;; load program address into EAX
        mov  [location], eax  ;; store address in local C++ variable
        pop eax               ;; restore EAX
        jmp  [location]       ;; jump using address in local C++ variable
    }

    // Display the address:
    cout << std::hex << location << std::dec << '\n';

    //----------------------------------------------------------------
    // Another demo using inline assember and local variable
    //----------------------------------------------------------------
    unsigned int mask = ( 1u << 31 ); // set highest bit to 1
    //mask = mask >> 1;               // inline assember instead of operator >>
    __asm {                           ;; begin inline assembly
        push eax                      ;; preserve EAX
        mov eax, [mask]               ;; load value from local C++ variable
        shr eax, 1                    ;; shift bits right
        mov [mask], eax               ;; save value in local C++ variable
        pop eax                       ;; restore EAX
    }
}