Mixed C and MASM with MASM Main Language, No C Run-Time (86815)
The information in this article applies to:
- Microsoft Macro Assembler (MASM) 5.0
- Microsoft Macro Assembler (MASM) 5.1
- Microsoft Macro Assembler (MASM) 5.1a
- Microsoft Macro Assembler (MASM) 6.0
- Microsoft Macro Assembler (MASM) 6.0a
- Microsoft Macro Assembler (MASM) 6.0b
- Microsoft Macro Assembler (MASM) 6.1
This article was previously published under Q86815 SUMMARY
The following steps should be used when doing mixed-language
programming between the Microsoft Macro Assembler (MASM) and Microsoft
C with MASM as the main language and when no C run-time will be used:
- Include the statement
in the assembly module to ensure that the modules use the same
default segments. The <model> will be small, medium, compact, or
large.
- Use the END directive in the assembly module to specify the entry
point.
- Compile the C module with /Gs to avoid generation of calls to the
stack checking routine.
- If the C compiler is version 5.1, include the following statement
in the C module to ensure that the startup code is not brought in:
int _acrtused = 0;
- Assemble the assembly module with /Mx to preserve the case of
nonlocal names. If MASM 6.0 or later is being used, use /Cx to
preserve the case of nonlocal names.
Note that the only contributions to the stack segment come from the
assembly module.
MORE INFORMATION
The following is a mixed-language sample. There is one C module and
one assembly module that must be compiled and then linked together. No
special link options are needed.
The sample declares two words, arg1 and arg2, converts them to
dollar-terminated strings, prints out their values to the screen, and
passes their addresses to a C routine. The C routine swaps the values
of arg1 and arg2. The values of arg1 and arg2 are printed out a second
time to show that they have been swapped.
NOTE: The EXTRN directive changed to EXTERN in MASM 6.1 All instances of
EXTRN should be changed to EXTERN in the sample code below if you are using
MASM version 6.1 or later.
Sample Code
/* Compile options needed: /Gs
*/
/* Uncomment the following line for C 5.1 to ensure that the startup
code is not brought in:
int _acrtused = 0;
*/
void ptrswap( int *ptr1, int *ptr2 )
{
int temp;
temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
----------------------------------------------------------------------
; Assemble options needed: /Mx
.MODEL small
Display MACRO string ; Print a "$" terminated string
MOV ah, 9
MOV dx, offset string
INT 21h
ENDM
.STACK
.DATA
arg1 DW 1234
arg2 DW 4321
outstr1 DB "Arg1: ", "$"
outstr2 DB "Arg2: ", "$"
newline DB 13, 10, "$" ; Carriage return-linefeed
converted DD ? ; Will contain arg1 or arg2 after
DB "$" ; they are converted
.CODE
EXTRN _ptrswap:proc ; External C routine
cnvrt PROC
; ******** Convert a word to a dollar-terminated string. *******
PUSH bp ; Establish
MOV bp, sp ; stack frame
MOV ax, [bp+4] ; Get first argument off stack
MOV bx, offset converted
MOV cx, 10
MOV si, 3 ; Index for storing in converted
nextdigit:
MOV dx, 0
DIV cx ; Divide ax by cx
ADD dl, "0" ; Convert to ASCII value
MOV [bx][si], dl ; Save digit in converted
DEC si ; Decrement index
CMP si, 0FFFFh ; Are we done?
JNZ nextdigit
ADD sp, 2 ; Destroy argument
RET ; Return
cnvrt ENDP
; ********************************************************************
start:
MOV ax, @data ; Load the data
MOV ds, ax ; segment register
; Print "Arg1: <value>" where <value> is the value of arg1
Display outstr1 ; Use display macro
MOV ax, arg1
PUSH ax ; Push argument
CALL cnvrt ; Call the convert procedure
Display converted ; Use display macro
Display newline ; Use display macro
; Print "Arg2: <value>" where <value> is the value of arg2
Display outstr2 ; Use display macro
MOV ax, arg2
PUSH ax ; Push argument
CALL cnvrt ; Call the convert procedure
Display converted ; Use the display macro
Display newline ; Use the display macro
Display newline ; Use the display macro
; Call the C module to swap the values of arg1 and arg2
MOV bx, offset arg2
PUSH bx ; Push the 2nd argument
MOV bx, offset arg1
PUSH bx ; Push the 1st argument
CALL _ptrswap ; Call the C routine
; Print out arg1 again, to show that it has changed
Display outstr1 ; Use display macro
MOV ax, arg1
PUSH ax ; Push argument
CALL cnvrt ; Call the convert procedure
Display converted ; Use display macro
Display newline ; Use display macro
; Print out arg2 again, to show that it has changed
Display outstr2 ; Use display macro
MOV ax, arg2
PUSH ax ; Push argument
CALL cnvrt ; Call the convert procedure
Display converted ; Use display macro
Display newline ; Use display macro
MOV ah, 4ch ; Terminate program
int 21h
END start ; Specify entry point as _start
Modification Type: | Major | Last Reviewed: | 10/17/2003 |
---|
Keywords: | KB86815 |
---|
|