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:
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:
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:
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 = "aaa": typevar.b = "bb": stringvar = "c": 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