Microsoft KB Archive/70664

= Must Pad Odd-Length Variables in COMMON Passed to MASM, C =

Article ID: 70664

Article Last Modified on 8/16/2005

-

APPLIES TO


 * Microsoft QuickBasic 4.0
 * Microsoft QuickBASIC 4.0b
 * Microsoft QuickBasic 4.5 for MS-DOS
 * Microsoft BASIC Compiler 6.0
 * Microsoft BASIC Compiler 6.0b
 * Microsoft BASIC Professional Development System 7.0
 * Microsoft BASIC Professional Development System 7.1
 * Microsoft Macro Assembler 6.0 Standard Edition
 * Microsoft Macro Assembler 6.0a
 * Microsoft Macro Assembler 6.0b
 * Microsoft Macro Assembler 6.1 Standard Edition

-



This article was previously published under Q70664



SUMMARY
Note that Basic automatically aligns each variable in COMMON on an even-byte boundary.

This means that when you pass odd-length fixed strings or odd-length user-defined TYPEs in a COMMON block from Basic to assembler or C, you must align the assembler or C structure variables that receive the COMMON onto even-byte boundaries. You must align variables correctly or their contents will be corrupted. You must always add padding for odd-length COMMON variables in assembler structures, but padding is necessary in C only if you compile the C code with the /Zp1 switch.

This information applies to Microsoft QuickBasic versions 4.00, 4.00b, and 4.50 for MS-DOS; to Microsoft Basic Compiler versions 6.00 and 6.00b for MS-DOS and MS OS/2; to Microsoft Basic Professional Development System (PDS) versions 7.00 and 7.10 for MS-DOS and MS OS/2; to all versions of the Microsoft Macro Assembler (MASM); and to supported versions of the Microsoft C Compiler.



MORE INFORMATION
Basic aligns all COMMON variables on even-byte boundaries for better data-addressing speed. This alignment affects assembler programmers more often than it affects C programmers.

Discussion for C
First, note that if any element (other than the last element) within a user-defined-TYPE variable passed to C has an odd length, then you must compile the C code with the /Zp1 option (to align C structures on byte boundaries instead of on word boundaries). /Zp1 is not necessary if just the last element within the user-defined TYPEs are odd.

If you compile the C code with /Zp1, then you must add 1 byte of padding in the C structure after each variable that has an odd overall length in Basic's COMMON. (Do not add padding between elements of a user-defined-TYPE variable or record; just add 1 byte of padding after the user-defined TYPE record if the record has an odd length.)

If /Zp1 is not required, and you compile the C code without /Zp1, then do not pad the C structure after odd-length COMMON variables, since they will be automatically word aligned.

For more information about calling C from Basic, query using the following word:

BAS2C

For more information about when /Zp1 is required when passing user-defined TYPEs from Basic to C, search for a separate article using the following words:

/Zp1 and odd and Basic

Discussion for MASM
In the assembly code, you must add a DB 1 DUP (?) statement after variables or user-defined-TYPE records in COMMON whose total length is odd.

The following assembler program demonstrates how odd-length variables should be padded to align with Basic's COMMON. The first variable in the COMMON is a user-defined TYPE with an overall length of 5 (no padding is allowed within a user-defined TYPE), so 1 byte of padding is added to the assembly language. The second variable is a fixed-length string of length 1. This is an odd length, so another byte of padding is needed. The last variable is an integer; since integers are stored in 2 bytes, no padding should be added.

If you are not sure how large is a variable of given TYPE, you can use the LEN function to return the length of that variable. For example, if you had DIM var AS SomeUserType then LEN(var) returns the number of bytes in SomeUserType.

Note: The passing of Basic dynamic arrays within COMMON blocks to other languages is not supported. This would require knowledge of the format of the array descriptor, which is considered proprietary information. With static arrays, the entire array is put directly within the COMMON block.

For more information about calling assembler from Basic, query on the following word:

BAS2MASM

Compile and link the code (further below) as follows: BC BAS; MASM MASM; LINK BAS+MASM; The Basic program will create four variables and store the following values values into them:   aaa, bb, c, &H1111 The assembly language will then modify the variables to be:   Xaa, Xb, X, &H1211

BAS.BAS
DECLARE SUB MasmProc TYPE rectype a AS STRING * 3 b AS STRING * 2 END TYPE ' Basic stores the following three variables contiguously in one ' COMMON named vars: COMMON SHARED /vars/ typevar AS rectype COMMON SHARED /vars/ stringvar AS STRING * 1 COMMON SHARED /vars/ intvar AS integer typevar.a = &quot;aaa&quot;: typevar.b = &quot;bb&quot;: stringvar = &quot;c&quot;: intvar = &H1111 CALL MasmProc PRINT typevar.a: PRINT typevar.b: PRINT stringvar: PRINT hex$(intvar)

MASM.ASM
rectype STRUC a  db  3 dup (?) b  db  2 dup (?) rectype ENDS

vars SEGMENT COMMON 'BC_VARS' typevar    rectype 1 dup (<>) db     1 dup (?)       ; pad typevar to word boundary stringvar  db      2 dup (?) db     1 dup (?)       ; more padding intvar     dw      1 dup (?) vars ENDS

dgroup GROUP vars .model medium, basic .code PUBLIC MasmProc MasmProc   PROC push   bp                      ; preserve bp    mov     typevar.a, 'X'              ; modify variables mov    typevar.b, 'X'    mov     stringvar, 'X'    inc     intvar pop    bp    ret MasmProc   ENDP END

Additional query words: QuickBas BasicCom

Keywords: KB70664

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.