KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q104644: INFO: Passing C Arrays to MASM by Reference

Article: Q104644
Product(s): Microsoft C Compiler
Version(s): 1.0,1.5,2.0,4.0,5.0,6.0,7.0
Operating System(s): 
Keyword(s): kbLangC kbVC100 kbVC150 kbVC200 kbVC400 kbVC500 kbVC600
Last Modified: 29-NOV-2001

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft C for MS-DOS 
- Microsoft C for OS/2 
- Microsoft C/C++ for MS-DOS, version 7.0 
- Microsoft Visual C++, versions 1.0, 1.5, 2.0, 4.0 
- Microsoft Visual C++, 32-bit Enterprise Edition, versions 5.0, 6.0 
- Microsoft Visual C++, 32-bit Professional Edition, versions 5.0, 6.0 
- Microsoft Visual C++, 32-bit Learning Edition, version 6.0 
-------------------------------------------------------------------------------

SUMMARY
=======

The sample code below demonstrates how to pass C arrays of type char, short, and
long to a Microsoft Macro Assembler (MASM) procedure by reference.

MORE INFORMATION
================

The samples below include one C file and three different assembly files. The
three assembly files demonstrate how to pass variables by reference in small
model and large model for MS-DOS and in flat model for Windows NT. Link only the
appropriate assembly module to the C module.

Note that MASM 6.1 or later and the C/C++ 32-bit compiler that ships with Visual
C++, 32-bit Edition, are required to build the flat model Windows NT version.

Sample Code
-----------

  // Filename: CMAIN.C
  // Compile options needed: /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};

  main ()
  {
     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", longarray[0], longarray[1], longarray[2]);
  }

Sample Code for MS-DOS Small Model Version
------------------------------------------

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

  .MODEL small, C
  .286
  .CODE

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

     mov si, arraychar  ; Load SI with the address of the char array.
     mov BYTE PTR [si], "x"       ; Since a char is 1 byte long, each
     mov BYTE PTR [si+1], "y"     ; successive element can be accessed
     mov BYTE PTR [si+2], "z"     ; by adding 1 more to si.
     mov si, arrayshort ; Load SI with the address of the short array.
     add WORD PTR [si], 7         ; Since a short is 2 bytes long, each
     add WORD PTR [si+2], 7       ; successive element can be accessed
     add WORD PTR [si+4], 7       ; by adding 2 more to si.
     mov si, arraylong  ; Load SI with the address of the long array.
     add WORD PTR [si], 1         ; Since a long is 4 bytes long, each
     adc WORD PTR [si+2], 0       ; successive element in the array
     add WORD PTR [si+4], 1       ; can be accessed by adding 4 more
     adc WORD PTR [si+6], 0       ; to si (or 4 more to si+2 to access
     add WORD PTR [si+8], 1       ; the high word of each element).
     adc WORD PTR [si+10], 0
     ret
  MasmSub ENDP
  END

Sample Code for MS-DOS Large Model Version
------------------------------------------

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

     .MODEL large, C
     .286
     .CODE

     MasmSub PROC uses es si, \ 
        arraychar:PTR, \ 
        arrayshort:PTR, \ 
        arraylong:PTR

        les si, arraychar  ; Load ES:SI with the address of the char array.
        mov BYTE PTR es:[si], "x"    ; Since a char is 1 byte long, each
        mov BYTE PTR es:[si+1], "y"  ; successive element can be accessed
        mov BYTE PTR es:[si+2], "z"  ; by adding 1 more to si.
        les si, arrayshort ; Load ES:SI with the address of the short array.
        add WORD PTR es:[si], 7      ; Since a short is 2 bytes long, each
        add WORD PTR es:[si+2], 7    ; successive element can be accessed
        add WORD PTR es:[si+4], 7    ; by adding 2 more to si.
        les si, arraylong  ; Load ES:SI with the address of the long array.
        add WORD PTR es:[si], 1      ; Since a long is 4 bytes long, each
        adc WORD PTR es:[si+2], 0    ; successive element in the array
        add WORD PTR es:[si+4], 1    ; can be accessed by adding 4 more
        adc WORD PTR es:[si+6], 0    ; to si (or 4 more to si+2 to access
        add WORD PTR es:[si+8], 1    ; the high word of each element).
        adc WORD PTR es:[si+10], 0
        ret
     MasmSub ENDP
     END
   

Sample Code for Windows NT Flat Model Version
---------------------------------------------

  ; 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

The following is the output of the program:

 abc
 1 2 3
 32768 32769 32770
 xyz
 8 9 10
 32769 32770 32771

Additional query words: mixed language

======================================================================
Keywords          : kbLangC kbVC100 kbVC150 kbVC200 kbVC400 kbVC500 kbVC600 
Technology        : kbVCsearch kbVC400 kbAudDeveloper kbZNotKeyword8 kbvc150 kbvc100 kbCCompSearch kbZNotKeyword3 kbCVC700DOS kbVC500 kbVC600 kbVC200 kbVC32bitSearch kbVC500Search
Version           : :1.0,1.5,2.0,4.0,5.0,6.0,7.0
Issue type        : kbinfo

=============================================================================

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.