Combining C++ and Assembly
jbwyatt.com

.. HLL to Assembly Code

HLL compilers translate mathematical expressions into assembly language.
You can do it also.

For example:

   Rval = -Xval + (Yval – Zval);

      .data
         Rval DWORD ?
         Xval DWORD 26
         Yval DWORD 30
         Zval DWORD 40

      .code
         mov eax,  Xval
         neg eax          ; EAX = -26
         mov ebx,  Yval
         sub ebx,  Zval   ; EBX = -10
         add eax,  ebx
         mov Rval, eax    ; -36

.. C++ Code


Hello World Progression
Metric
Stick Figure (functions)
// cFuncs.cpp // Shows Menu // Allows user to input choice // Code calls a function in response to user choice #include <iostream> int Func1(int); int Func2(int, int); int Func3(int, int, int); void Func4(void); using namespace std; int main( ) { int first, second, third, answer; int choice = 0; do { // menu cout << "0. get three new inputs\n"; cout << "1. double, add 10 and negate\n"; // more code // etc... cout << "5. exit\n" cin >> choice; if (choice == 0) { // Get user input cout << "Enter 3 numbers separated by spaces & hit enter: "; cin >> first >> second >> third; } else if (choice == 1) { // Call function, get return and output answer = Func1(first); cout << "The answer for ..." << answer << endl; } // more menu code // etc... } while (choice != 5); return 0; } // other functions //etc...

.. Disassembly Code

DISASSEMBLY: C++ to Assembly - example...
 ===========================

 random code from a sudoku program...

 case 1:
        ////////////////////////////////////////////////////
        // generate & print simple grid WITH repetitions
        //
        ///////////////////////////////////////////////////
        timeStart = time(0); 
0044E4FA  push        0
0044E4FC  call        time (44EE00h)
0044E501  add         esp,4
0044E504  mov         dword ptr [ebp-68h],eax

        // allocate dynamic memory on the heap
        grid1=new int[SZp*SZp];
0044E507  mov         eax,dword ptr [ebp-80h]
0044E50A  imul        eax,dword ptr [ebp-80h]
0044E50E  xor         ecx,ecx
0044E510  mov         edx,4
0044E515  mul         eax,edx
0044E517  seto        cl
0044E51A  neg         ecx
0044E51C  or          ecx,eax
0044E51E  push        ecx
0044E51F  call        operator new[] (440ADCh)
0044E524  add         esp,4
0044E527  mov         dword ptr [ebp-248h],eax
0044E52D  mov         eax,dword ptr [ebp-248h]
0044E533  mov         dword ptr [ebp-14h],eax

        // init grids to all zeroes
        initGridP(grid1, SZp);
0044E536  mov         eax,dword ptr [ebp-80h]
0044E539  push        eax
0044E53A  mov         ecx,dword ptr [ebp-14h]
0044E53D  push        ecx
0044E53E  call        initGridP (440820h)
0044E543  add         esp,8

        // generate grid using random numbers(1 to gridsize)
        simpleGridP(grid1, SZp);
0044E546  mov         eax,dword ptr [ebp-80h]
0044E549  push        eax
0044E54A  mov         ecx,dword ptr [ebp-14h]
0044E54D  push        ecx
0044E54E  call        simpleGridP (4406DBh)
0044E553  add         esp,8
        printGridP(grid1, SZp);
0044E556  mov         eax,dword ptr [ebp-80h]
0044E559  push        eax
0044E55A  mov         ecx,dword ptr [ebp-14h]
0044E55D  push        ecx
0044E55E  call        printGridP (441ED7h)
0044E563  add         esp,8
        cout << "Simple random grid with NO CHECK for repetitions..." << endl;
0044E566  push        offset std::endl (44077Bh)
0044E56B  push        offset string "Simple random grid with NO CHECK"... (4C5EC0h)
0044E570  push        offset std::cout (4DEFE0h)
0044E575  call        std::operator<< > (441248h)
0044E57A  add         esp,8
0044E57D  mov         ecx,eax
0044E57F  call        std::basic_ostream >::operator<< (441284h)

        // release allocated memory
        delete []grid1;
0044E584  mov         eax,dword ptr [ebp-14h]
0044E587  mov         dword ptr [ebp-23Ch],eax
0044E58D  mov         ecx,dword ptr [ebp-23Ch]
0044E593  push        ecx
0044E594  call        operator delete[] (4401EAh)
0044E599  add         esp,4

        // time stamp
        cout << "Seconds used is " << time(0)-timeStart << endl;
0044E59C  push        offset std::endl (44077Bh)
0044E5A1  push        0
0044E5A3  call        time (44EE00h)
0044E5A8  add         esp,4
0044E5AB  mov         ecx,eax
0044E5AD  mov         esi,edx
0044E5AF  mov         eax,dword ptr [ebp-68h]
0044E5B2  cdq
0044E5B3  sub         ecx,eax
0044E5B5  sbb         esi,edx
0044E5B7  push        esi
0044E5B8  push        ecx
0044E5B9  push        offset string "Seconds used is " (4C5EACh)
0044E5BE  push        offset std::cout (4DEFE0h)
0044E5C3  call        std::operator<< > (441248h)
0044E5C8  add         esp,8
0044E5CB  mov         ecx,eax
0044E5CD  call        std::basic_ostream >::operator<< (441D29h)
0044E5D2  mov         ecx,eax
0044E5D4  call        std::basic_ostream >::operator<< (441284h)
         break;
0044E5D9  jmp         $LN4+62h (44EAECh)

 

.. Mixed Code: __asm Blocks in C++

__asm
{
  assembly code
}

   
The __asm (2 underscores!!) keyword invokes the inline assembler and 
can appear wherever a C++ statement is legal and must be followed by 
an assembly instruction or a group of assembly instructions in braces. 

The inline assembler lets you embed assembly-language instructions in 
your C and C++ source programs. 

It's built into the compiler, so you don't need a separate assembler .

Inline assembly code can use any C or C++ variable or function name that 
is in scope, so it's easy to integrate with your program's C and C++ code. 

Because the assembly code can be mixed with C and C++ statements, it 
can do tasks that are cumbersome or impossible in C or C++ alone.

Example Code:
=============
    __asm 
   { 
      mov al, 2 
      mov dx, 0xD007 
      out dx, al 
   } 
OR, you can put __asm before each assembly instruction:

   __asm  mov al, 2 
   __asm  mov dx, 0xD007 
   __asm  out dx, al 

Can NOT use assembler directives including data defintions. Can only use registers and variables declared in C++.
Example Program: ================ #include <iostream> using namespace std; int main() { int x; __asm { mov AL, -128 neg AL mov AX, 8000h add AX, 2 mov AX, 0 sub AX, 2 mov AL, -5 sub AL, +125 mov EAX, 2000 neg EAX mov x, EAX ; move the computed value into RAM at x } cout << x; return 0; }
Example Program: ================ add 3 to 9 equals 12 (in EAX) subtract 2 getting 10 (in EAX) negate giving -10 (EAX) move into C++ variable, number print the variable (-10) #include <iostream> using namespace std; int main() { int number=3; __asm { mov EAX, 00000009h add EAX, number ; add 3 mov EBX, 2 sub EAX, EBX ; 12 - 2 = 10 neg EAX mov number, EAX } cout << number; ; -10 return 0; }