Microsoft KB Archive/106399

From BetaArchive Wiki

Article ID: 106399

Article Last Modified on 8/5/2005



APPLIES TO

  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++ 6.0 Standard Edition
  • Microsoft Macro Assembler 6.15



This article was previously published under Q106399

SUMMARY

Versions of Microsoft Visual C++ version 4.0 and later do not support assembler source files by default. That is, the Developer Studio does not associate any special significance to .asm files without being informed otherwise. However, there are several viable options, namely custom build rules, which enable the creation of projects that depend directly upon assembler source files.

The remainder of this article discusses the following four methods for adding .ASM files to a Visual C++ project:

  1. Using custom build rules
  2. Modifying a VWB makefile and using it as an external makefile
  3. Using an external makefile to assemble the assembly modules and then using an internal makefile for the main program
  4. Creating an option on the VWB Tools menu to assemble each assembly module as needed

Of these methods, the use of custom build rules receives special attention. This powerful construct debuts in Visual C++ version 4.0. By utilizing a custom build rule, a project can invoke MASM on a per file basis to assemble .asm files. The resulting object modules can then be linked into the desired target.

MORE INFORMATION

Method 1

Using Visual C++ Developer Studio, the following provides sample code and a step-by-step example of how to create a simple console application, CAPP, that requires MASM (Ml.exe) to assemble one of its source files. Note that the sample code for this example was borrowed from the following Microsoft Knowledge Base article:

104644 How to pass C arrays of type char, short, and long to a MASM procedure by reference


Method 1: Sample code - C module

/* Filename: CMAIN.C */ 

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

void MasmSub (char *, short *, long *);

#ifdef __cplusplus
}
#endif

char chararray[4] = "abc";
short shortarray[3]  = {1, 2, 3};
long longarray[3] = {32768, 32769, 32770};

void main( void )
{
   printf ("%s\n", chararray);
   printf ("%d %d %d\n", shortarray[0], shortarray[1], shortarray[2]);
   printf ("%ld %ld %ld\n", longarray[0], longarray[1], longarray[2]);
   MasmSub (chararray, shortarray, longarray);
   printf ("%s\n", chararray);
   printf ("%d %d %d\n", shortarray[0], shortarray[1], shortarray[2]);
   printf ("%ld %ld %ld\n", longarray[0], longarray[1], longarray[2]);
}
                

Method 1: Sample code - ASM module

; Filename: MASMSUB.ASM
; Assemble options needed for ML: /c /Cx /coff

.386
.MODEL flat, C
.CODE

MasmSub PROC uses esi, \ 
   arraychar:PTR, \ 
   arrayshort:PTR, \ 
   arraylong:PTR

   mov esi, arraychar ; Load ESI with the address of the char array.
   mov BYTE PTR [esi], "x"      ; Since a char is 1 byte long, each
   mov BYTE PTR [esi+1], "y"    ; successive element can be accessed
   mov BYTE PTR [esi+2], "z"    ; by adding 1 more to esi.
   mov esi, arrayshort; Load ESI with the address of the short array.
   add WORD PTR [esi], 7        ; Since a short is 2 bytes long, each
   add WORD PTR [esi+2], 7      ; successive element can be accessed
   add WORD PTR [esi+4], 7      ; by adding 2 more to esi.
   mov esi, arraylong ; Load ESI with the address of the long array.
   inc DWORD PTR [esi]          ; Since a long is 4 bytes long, each
   inc DWORD PTR [esi+4]        ; successive element can be accessed
   inc DWORD PTR [esi+8]        ; by adding 4 more to esi.
   ret
MasmSub ENDP
END
                

Method 1: Step-by-step instructions for building CAPP

Use the following steps to create the project:

  1. Start the Visual C++ Developer Studio, Msdev.exe.
  2. Create and save Cmain.c and MasmSub.asm.
  3. From the File menu, select New. Create a new console application named CAPP.

For Visual C++, version 4.0, follow these steps to build the project:

  1. From the Insert menu, choose Files into Project. In the Insert Files into Project dialog box, select Cmain.c as a Common File Type and press OK.
  2. From the Insert menu, choose Files into Project. In the Insert Files into Project dialog box, select MasmSub.asm as an All Files Type and press OK.
  3. From the Build menu, choose Settings. In the Settings For list box in the Project Settings dialog box, expand the "CAPP - Win32 Debug" target such that MasmSub.asm is visible. Highlight only MasmSub.asm.
  4. Select the Custom Build tab.
  5. In the first line of the Build command(s) box, enter the full path and file name for MASM, the desired build options, and the macro for the File Input Path. The latter can be obtained by pressing the Files button and selecting Input Path from the resulting menu. If Ml.exe is in the C:\MASM611A\BIN directory, the entry would appear as follows:

    C:\MASM611A\BIN\ML.EXE /c /Cx /coff $(InputPath)

  6. In the first line of the Output files(s) box, enter MasmSub.obj.
  7. Press OK in the Project Settings dialog box to save your changes. (This also selects the default build options for Cmain.c.)
  8. The "CAPP - Win32 Debug" target is now ready to be built. From the Build menu, select Rebuild All. First, Ml.exe will be invoked to compile MasmSub.asm, second, Cl.exe will be invoked to compile Cmain.c, and third, Link.exe will be invoked to generate Capp.exe.
  9. The following is the console output of Capp.exe:

       abc
       1 2 3
       32768 32769 32770
       xyz
       8 9 10
       32769 32770 32771
                            
  10. To build the "CAPP - Win32 Release" target, select its name in the Target drop-down list box on the Project Workspace toolbar. Then, repeat steps 6 through 11 substituting the release version of the target for the debug version.

For Visual C++, versions 5.0 and 6.0, follow these steps to build the project:

  1. On the Project menu, point to Add To Project, and then click Files.
  2. Find and select both Cmain.c and MasmSub.asm.
  3. On the Project menu, click Settings.
  4. On the Project Settings dialog box, select All Configurations in the Settings For list.
  5. Click the Custom Build tab.
  6. In the first line of the Build command(s) box, enter the full path and file name for MASM, the desired build options, and the macro for the File Input Path. The latter can be obtained by pressing the Files button and selecting Input Path from the resulting menu. If Ml.exe is in the C:\MASM611A\BIN directory, the entry would appear as follows:

    C:\MASM611A\BIN\ML.EXE /c /Cx /coff $(InputPath)

  7. In the first line of the Output files(s) box, enter MasmSub.obj.
  8. On the Build menu, click Batch Build. Select the desired configurations and click the Rebuild All button.

For more information on custom build rules, see the Visual C++ online Help for the Custom Build Tab (press the Help button in the Project Settings dialog box when the Custom Build tab is selected).

Method 2

Modify a Visual WorkBench makefile and then use it as an external makefile. To do this, use the following steps:

  1. Open or create a project with the VWB and set it up as desired for the C/C++ files in the project.
  2. Close the project and modify the .MAK file to include build rules for the assembly modules.
  3. Put a comment at the start of the file to force the VWB to read the file as an external makefile; otherwise, you could lose your changes.

The primary disadvantage of this method is you cannot use the VWB options to change the way a build is done with an external makefile.

Method 3

Use an external makefile to assemble the assembly modules, and use an internal makefile for the main program, which includes the MASM .obj files built with the external makefile. Simply add the .obj files to the project list.

With this method, remember to load the external makefile and build the .obj files after changing any MASM code. By doing this, you can still use the VWB to modify options for the main project, including switching from debug to release. The linker will drop the CodeView information if you select release build for the main project, so always having the debug switches on for the assembler files is not a problem.

Method 4

Create an option on the VWB Tools menu to assemble each assembly module as needed. The following setups can be used to create Tools menu items that build the current file:

  1. From the Tools menu, choose the Customize option.
  2. Select the Tools tab in the Customize dialog box. Press Add.
  3. Specify the complete path to Ml.exe in the Command edit field of the Add Tool dialog box, or use the Browse button feature, and press OK.
  4. Set up the Ml.exe menu option as follows:

          Menu Text:          &Assemble Current File
          Command:            <should be set from step 3 above>
          Arguments:          /c /Zi /Fl /Sa $FileName
          Initial Directory:  $FileDir
          Check the box for:  "Prompt for Arguments"
          Check the box for:   "Redirect to Output Window"
                            
  5. Press the Close button.

The assembly results will appear in the build output window. You can use F4 to jump to lines containing errors in the source window.


Additional query words: VWBIss

Keywords: kbinfo kbtshoot kbide kbenv KB106399