C And Assembly

 < Day Day Up > 



C++ And Assembly

Assembly language routines can generally be added to C++ programs in two ways: by embedding the assembly language statements directly in a C++ function, and by incorporating an object file created by an assembler in your project. In this section I will show you how to do both for the PC and Macintosh computing platforms.

Some Things To Think About Before Using Assembly

As with just about any decision you will make in your programming career the one regarding the use of assembly language in your C++ program should not be made willy-nilly. Some things to consider include the following:

  • Efficient Processor Usage - Old assembly language routines may not use modern processors efficiently. As a rule, new processor versions introduce new instructions. Old versions of assembly language will most certainly not support these new instructions.

  • Code Optimization - Face it, compilers generate better optimized code than do humans. If your reasons for using assembly include the one 'I can do it better' I recommend letting the compiler have a go at it first.

  • Portability - Adding assembly to your C++ program will lock it into a specific processor and severely limit your code portability.

  • Maintenance - As time passes, assembly routines embedded directly in your C++ code will have to be upgraded more frequently than the C++ instructions to take advantage of new processor features.

Know Thy Implementation Dependencies

Many implementation aspects of the C++ language are left to the discretion of the compiler manufacturer, and how each enables the integration of assembly language into your C++ code is one of the most implementation dependent aspects of all. For example, the method used to embed assembly language directly into a C++ function differs in Metrowerks CodeWarrior Release 5 between the PC and the Macintosh versions of the compiler. Your best resource for information regarding the use of assembly within your C++ code resides somewhere in your development environment's documentation.

Inline Assembly Language in a C++ Function

Assembly code can be embedded directly into the body of a C++ function by using the asm keyword. How the asm keyword is actually employed in your development environment is - you guessed it - implementation dependent. I will start first with a PC version. Example 18.5 gives the code for a header file that declares a function named doubleVal().

Listing 18.5: double.h

start example
 1   #ifndef DOUBLE_H 2   #define DOUBLE_H 3 4   int doubleVal(int d); 5 6   #endif
end example

The doubleVal() function takes an integer argument and returns its doubled value. Example 18.6 implements the doubleVal() function with embedded assembly that targets an Intel® processor.

Listing 18.6: double.cpp

start example
  1  #include "double.h"  2  3  int doubleVal(int d){  4      int return_val;  5      asm{  6         mov eax, d            ;move d into the eax register  7         shl eax, 1            ;shift eax bits left by 1 bit  8         mov return_val, eax   ;move result into return_val   9         } 10      return return_val; 11  }
end example

There are several important things to note in this example. First, the assembly instruction block is introduced with the asm keyword. Second, local variables and parameter names can be used as necessary in the assembly block. Also, Metrowerks CodeWarrior Release 5 allows the use of either the asm keyword or the _asm keyword.

Example 18.6 can now be used in a Win32 project. This is shown in figure 18-14.

click to expand
Figure 18-14: Win32 Project Using Inline Assembly Language

The doubleVal() function is used in a main() function and the results of running the project are shown in figure 18-15.

click to expand
Figure 18-15: Results of Running the Inline Assembly Project

Linking An Object File Created From Assembly Language

This section will show you how to create a stand-alone assembly language routine, generate an object file, and use it in a C++ project. The target platform used for this demonstration is Win32. The assembly language file is assembled with Microsoft Macro Assembler (MASM) version 6.14 and used in a C++ Win32 project created using Metrowerks CodeWarrior Release 5.

Process Steps

The steps required to create an object file from assembly language and add it to a C++ project are listed below and illustrated in figure 18-16.

  • Step 1 - Create assembly language file with a text editor and save it with the .asm extension,

  • Step 2 - Assemble the file to create a Portable Executable/Common Object File Format (PE/ COFF) object file,

  • Step 3 - Create a C++ project using the development system of your choice,

  • Step 4 - Create a header file that declares the name of the function contained in the object file. The function declaration must be declared to have extern 'C' language linkage.

  • Step 5 - Add the object file to the C++ project,

  • Step 6 - Compile and run the project and do a victory dance!

    click to expand
    Figure 18-16: Adding Assembly Object File to C++ Project

Step 1: Create Assembly Language File

Using your favorite text editor create the assembly language file and save it with a .asm extension. Example 18.7 gives the assembly listing for a file named double.asm that implements an assembly procedure named doubleVal.

Listing 18.7: double.asm

start example
1   .586 2   .MODEL flat, stdcall 3   .CODE 4   doubleVal PROC C int_val:DWORD 5             mov eax, int_val 6             shl eax, 1 7             ret 8   doubleVal endp 9   END
end example

Step 2: Assemble the .asm File

The assembly file now needs to be assembled into an object module. To run in a Win32 environment the object file needs to be in the PE/COFF object file format. Failure to generate the proper object file format will result in a link error.

For this example I am using Microsoft Macro Assembler version 6.14 via the command line. The command to assemble the double.asm file will look like this:

ml /c /coff /Fodv.obj double.asm

The results of running this command are shown in figure 18-17.

click to expand
Figure 18-17: Assembling double.asm with MASM ver. 6.14

Several MASM command line switches are used to obtain the right object module. First, the /c tells MASM to compile only and to not link the resulting file. The /coff switch creates a coff object module. The /Fo specifies the name of the output file. Running the assembler results in a coff object file named dv.obj that is ready to be used in a Win32 C++ project.

Step 3: Create a C++ Project

Create a Win32 C++ project using the IDE of your choice. The IDE of my choice is Metrowerks CodeWarrior and to it I have added a main.cpp file that calls the doubleVal() function. The code for the main.cpp file is shown in example 18-8.

Listing 18.8: main.cpp

start example
  1  #include <iostream>  2  #include "double.h"  3  using namespace std;  4  5  int main( void ){  6      for(int i=0; i<10; i++){  7       cout<<doubleVal(i)<<endl;  8      }  9      return 0; 10  }
end example

Step 4: Create a header File

Create the double.h header file as shown in example 18.9. Since the doubleVal() function was created in assembly language the function declaration must be declared to have extern 'C' language linkage.

Listing 18.9: double.h

start example
 1   #ifndef DOUBLE_H 2   #define DOUBLE_H 3 4   extern "C"{ 5   int doubleVal(int d); 6   } 7 8   #endif
end example

Make the header file available to the project in the usual fashion.

Step 5: Add the Object File to the Project

When the object and header files have been created you are ready to use the object file, and the function it implements, in a C++ project. Figure 18-18 shows a Metrowerks CodeWarrior Win32 project with the dv.obj file included.

click to expand
Figure 18-18: Win32 Project Using dv.obj

Step 6. Compile and Run the Project

Figure 18-18 also shows the results of running the project.

Using Inline Assembly in the Macintosh Environment

The syntax required to use inline assembly in a C++ program targeting the Macintosh platform is different from that required to target the PC. The obvious differences between assembly for the PC and assembly for the Macintosh will be the names and format of assembly instructions and the names and usages of the PowerPC registers. These issues are beyond the scope of this book, however, I do want to show you at least one example of inline assembly targeting the Macintosh.

I will implement the same doubleVal() function using Metrowerks CodeWarrior Release 5 for the Macintosh. Example 18.10 gives the code for the double.cpp file.

Listing 18.10: double.cpp PowerPC Version

start example
 1  #include "double.h" 2 3  asm int doubleVal(int int_val){ 4     lwz   r0, int_val   //load int_val into register 0 5     mulli r3, r0, 2     // multiply r0 by 2, store in r3 for return 6  }
end example

Note the differences between the Macintosh version of this file and the PC version. The asm keyword is still used but here it must precede the function definition. Local variable names can still be used in the assembly code as well as C++ style comments. Figure 18-19 shows the results of running the Macintosh version of the doubleVal() function.

click to expand
Figure 18-19: Results of Running Macintosh Version of doubleVal()

Quick Review

In this section you have learned how to incorporate assembly language into your C++ projects. The two primary methods of doing so are by including inline assembly instructions within a C++ function, or by creating stand-alone object modules with assembly language and linking those object modules to your C++ projects. Consult your compiler documentation to learn how it supports the asm keyword.



 < Day Day Up > 



C++ for Artists. The Art, Philosophy, and Science of Object-Oriented Programming
C++ For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504028
EAN: 2147483647
Year: 2003
Pages: 340
Authors: Rick Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net