'===========================================================================
' Subject: ASSEMBLY IN QBASIC 3: PASSING      Date: 02-19-97 (21:10)       
'  Author: Rick Elbers                        Code: QB, QBasic, PDS        
'  Origin: rick@tip.nl                      Packet: ASMCODE.ABC
'===========================================================================
'ASSEMBLY IN QBASIC 3: PASSING VARIABLES, ARRAYS, STRING to the STACK
'---------------------------------------------------------------------
'RICK ELBERS februari 1997
'---------------
'Introduction
'--------------

'This routine is exploring the way array's, long integers
'and strings are passed to the assembly routine. There will
'be developed efficient procedures for doing this.
'In addition I will demonstrate some of the uses you can make
'of this knowledge. You absolutely need to understand the
'informations and tools presented in this article to make
'some progress with assembly in QBASIC.
'And the other way around too: when you understand them well,I
'think you have ways to gooo.
'----------------------------------------------------------------
DEFINT A-Z

'INFORMATIONS:
'*************
DECLARE SUB integerinfo ()        'information about integer passing
DECLARE SUB longinfo (longs&)     'information about long passing
DECLARE SUB stringinfo (a$)       'information about variable string passing
DECLARE SUB fixedstringinfo ()    'information about fixed string passing

DECLARE SUB intarrayinfo ()       'information about integer array passing
DECLARE SUB intarrayinfo2 ()      'information about integer array passing 2
DECLARE SUB longarrayinfo ()      'information about long array passing
DECLARE SUB stringarrayinfo ()    'information about string array passing

DECLARE SUB typeinfo ()           'information about type passing

'DEMONSTRATIONS:
'***************
DECLARE FUNCTION dosprn$ ()       'demonstration of stringpassing
DECLARE SUB movearr2arr ()        'demonstration of integer array passing
DECLARE SUB swapstringarray ()    'demonstration of string array passing
DECLARE SUB ascicntdemo ()        'demonstration of long array passing

TYPE testtype
astring AS STRING * 5
ainteger AS INTEGER
along AS LONG
END TYPE

DIM SHARED test AS testtype
test.astring = "hallo"
test.ainteger = &HFFFF
test.along = &HF0F0F0F0

CLS
COLOR 0, 7: PRINT "Let us get some information about passing ..";
COLOR 7, 0:
VIEW PRINT 3 TO 25

PRINT : PRINT : PRINT "Press a key for integer pass info": SLEEP: CLS
CALL integerinfo
PRINT : PRINT : PRINT "Press a key for long integer pass info": SLEEP: CLS
CALL longinfo(&H123F546F)
PRINT : PRINT : PRINT "Press a key for string pass info ": SLEEP: CLS
CALL stringinfo("Wat is dit")
PRINT : PRINT : PRINT "Press a key for fixed string pass info ": SLEEP: CLS
CALL fixedstringinfo
PRINT : PRINT : PRINT "Press a key for integer array pass info": SLEEP: CLS
CALL intarrayinfo
CALL intarrayinfo2
PRINT : PRINT : PRINT "Press a key for long array pass info": SLEEP: CLS
CALL longarrayinfo
PRINT : PRINT : PRINT "Press a key for array of strings pass info ": SLEEP: CLS
CALL stringarrayinfo
PRINT : PRINT : PRINT "Press a key for type pass info ": SLEEP: CLS
CALL typeinfo
PRINT : PRINT "Press a key": SLEEP: VIEW PRINT: CLS

COLOR 0, 7: PRINT "Let us demonstrate barely the powers that we discovered..";
COLOR 7, 0:
VIEW PRINT 3 TO 25
PRINT : PRINT "Press a key for string print demo ": SLEEP: CLS 2

'Using this information we can write an efficient dosprn
COLOR 0, 7: PRINT "STRING PRINT DEMONSTRATION": COLOR 7, 0: PRINT :
asm$ = dosprn$: Codeoff = SADD(asm$):
DEF SEG = VARSEG(asm$): CALL absolute("HaHaThisisAll$", Codeoff)
DEF SEG

PRINT : PRINT : PRINT "Press a key for array movet demo ": SLEEP: CLS 2
'Using this information we can write an efficient movearray
CALL movearr2arr

PRINT : PRINT : PRINT "Press a key for stringswap demo ": SLEEP: CLS 2
'Using this information we can write an very efficient stringsort
CALL swapstringarray

PRINT : PRINT : PRINT "Press a key for ascicount(long array) demo ": SLEEP: CLS 2
CALL ascicntdemo

PRINT : PRINT : PRINT "Press a key for conclusions ": SLEEP: VIEW PRINT: CLS

'The use of stringarrays can hardly be overestimated. First they default
'to the stringsegment and second there location is stable. This makes them
'very useful for the storage of asm functions as we will see in the next
'issues of ASM in QBASIC. Also because of the descriptors you could sort
'a complete array of strings with a resultant indexarray of elements
'which make it possible to get the array sorted in QBASIC by:
'FOR i=lbound(arraystring$) TO ubound(arraystring$)
'    print arraystring$(index(i))
'NEXT
'This will be very very fast since the only thing you sort is the index
'and you are not going to copy the strings themselves....

PRINT SPACE$(30); : COLOR 0, 7: PRINT " CONCLUSIONS ": COLOR 7, 0
PRINT
COLOR 0, 7: PRINT " MEMORY LOCATIONS ": COLOR 7, 0
PRINT "- The memory LOCATIONS of integers, stringarrays and types are STABLE."
PRINT "- The memory LOCATION of a fixed length string is also STABLE."
PRINT "- A variable length string is prone to garbage collection(<>STABLE)."
PRINT
COLOR 0, 7: PRINT " MEANINGFULL STACKPASSING POSSIBILITIES ": COLOR 7, 0
PRINT "-You can pass all types of variables in a meaningful manner through"
PRINT " the stack except the FIXED LENGTH string."
PRINT
COLOR 0, 7: PRINT " PASSING BY VALUE ": COLOR 7, 0
PRINT "-INTEGERS and TYPES are the only 'variables' that are passed by VALUE by default"
PRINT "-It is possible to pass LONG integers by VALUE while using BYVAL"
PRINT
COLOR 0, 7: PRINT " PASSING BY REFERENCE ": COLOR 7, 0
PRINT "-All variables except INTEGERS and TYPES are passed by REFERENCE by default."
PRINT "-INTEGER/TYPE REFERENCING(pointing)is possible by reference to there STACKADRESS"
PRINT
COLOR 0, 7: PRINT " STRANGE BEHAVIORS ": COLOR 7, 0
PRINT "-Like Gunter Ilzig pointed out PASSING by REFERENCE is ALWAYS faster"
PRINT " This is also true for integer and type passing( strange fact)": PRINT

PRINT "Good bye"



END

DEFSTR A-Z
SUB ascicntdemo

COLOR 0, 7: PRINT "LONG ARRAY DEMONSTRATION": COLOR 7, 0: PRINT :

'---------------------------------------
'THIS FUNCTION TRIES TO SPEED UP
'THE SORT OF FREQUENCY OF CHARACTERS.
'EOF IS STORED TOO!

'STACKPASSING FREQ&(),A$

'IN: FREQ ARRAY
'    STRING TO CNT

'OUT FREQ ARRAY UPDATED

'Its just an example of the use of long
'array's..
'---------------------------------------

asm = asm + CHR$(&H55)                               'PUSH BP
asm = asm + CHR$(&H89) + CHR$(&HE5)                  'MOV BP,SP
asm = asm + CHR$(&H1E)                               'PUSH DS
asm = asm + CHR$(&H6)                                'PUSH ES
'DS[SI] TO STRING,CX TO LEN
asm = asm + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)      'MOV BX,[BP+06]
asm = asm + CHR$(&H8B) + CHR$(&HF)                   'MOV CX,[BX]  LENGTH
asm = asm + CHR$(&H8B) + CHR$(&H77) + CHR$(&H2)      'MOV SI,[BX+2]DS[SI] STRING
'ES[DI] TO ARRAY
asm = asm + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)      'MOV BX,[BP+08]
asm = asm + CHR$(&HC4) + CHR$(&H3F)                  'LES DI,[BX] ES[DI] ASCARRAY
asm = asm + CHR$(&HFC)                               'CLD         FUTURE
'LOOPJE:
asm = asm + CHR$(&HAC)                               'LODSB    DS[SI] > AL
asm = asm + CHR$(&H30) + CHR$(&HE4)                  'XOR AH,AH
asm = asm + CHR$(&HC1) + CHR$(&HE0) + CHR$(2)        'SHL AX,2 ASC TO INTELEMENT
asm = asm + CHR$(&H89) + CHR$(&HC3)                  'MOV BX,AX TO ADRESS IN ARRAY
asm = asm + CHR$(&H26) + CHR$(&HFF) + CHR$(&H7)      'ES:INC[BX]
asm = asm + CHR$(&H49)                               'DEC CX
asm = asm + CHR$(&H75) + CHR$(&HF2)                  'JNZ -12 ANOTHER ELEMENT ?

asm = asm + CHR$(&H7)                                'POP ES
asm = asm + CHR$(&H1F)                               'POP DS
asm = asm + CHR$(&H5D)                               'POP BP
asm = asm + CHR$(&HCA) + CHR$(&H4) + CHR$(&H0)       'RETF 4

ascicnt = asm
'-------------------------------------------------
'LONGDIVINT:
'This function is returning both the division
'and the remainder from an SDWORD to SWORD division.

'STACKPASSING Word&,Div&
'IN : Word& the Dword to divide
'     Div%  the word to divide by
'OUT: Word& the result of Longintegerdivision
'     DIv%  the remainder of the Longintegerdivision
'--------------------------------------------------
asm = ""
asm = asm + CHR$(&H55)                             'push bp         4
asm = asm + CHR$(&H89) + CHR$(&HE5)                'mov bp,sp       1

asm = asm + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)    'mov bx,[bp+0a]  1+9
asm = asm + CHR$(&H8B) + CHR$(&H7)                 'mov AX,[bx]     1+5 low
asm = asm + CHR$(&H8B) + CHR$(&H57) + CHR$(2)      'mov DX,[bx+2]   1+9 high
asm = asm + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)    'mov bx,[bp+06]  1+9
asm = asm + CHR$(&H8B) + CHR$(&HF)                 'mov CX,[bx]     1+5
asm = asm + CHR$(&HF7) + CHR$(&HF9)                'idiv cx         27
asm = asm + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)    'mov bx,[bp+0A]  1+9
asm = asm + CHR$(&H89) + CHR$(&H7)                 'mov [bx],ax     1+5
asm = asm + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)    'mov bx,[bp+08]  1+9
asm = asm + CHR$(&H89) + CHR$(&H17)                'mov [bx],dx     1+5

asm = asm + CHR$(&H5D)                             'pop bp          4
asm = asm + CHR$(&HCA) + CHR$(&H6) + CHR$(&H0)     'retf 4          14
longdivint = asm                                       'clocks     105

'Initiating functions ,arrays and string:
DIM freq&(255): a$ = SPACE$(10000):
FOR I% = 0 TO 255: freq&(I%) = 0: NEXT:

DEF SEG = &H40: POKE &H1C, PEEK(&H1A)
DEF SEG = VARSEG(ascicnt)

'Oke and lets go for it( you can hold your breath!even for 300 KB text!)

PRINT "Give a path of very large(< 100 MB) text file.. ";
f$ = "": DO UNTIL f$ <> "": COLOR 0, 7: LINE INPUT f$: LOOP: COLOR 7, 0
PRINT : a! = TIMER: OPEN f$ FOR BINARY AS #1
mods% = 10000: CALL absolute(LOF(1), divs%, mods%, SADD(longdivint))

FOR I% = 1 TO divs%
GET #1, , a$:
  '___________________________________________________________
  CALL absolute(freq&(), a$, SADD(ascicnt))
  '___________________________________________________________
NEXT
a$ = SPACE$(mods%): GET #1, , a$            'last part
CALL absolute(freq&(), a$, SADD(ascicnt))
leof& = LOF(1): CLOSE : DEF SEG
c! = TIMER
COLOR 0, 7: PRINT "Frekwenties of 'text' ASCI's"; : COLOR 7, 0: PRINT :
FOR I% = 32 TO 126:
  PRINT CHR$(I%); ":"; : PRINT USING "#######"; freq&(I%); : PRINT " "; :
  IF (I% - 32) MOD 8 = 7 THEN PRINT
NEXT
PRINT : PRINT
PRINT "For a file of "; : COLOR 0, 7: PRINT leof&; : COLOR 7, 0:
PRINT " bytes we needed "; : COLOR 0, 7: PRINT c! - a!; : COLOR 7, 0

END SUB

DEFSNG A-Z
FUNCTION dosprn$
'This functions prints a string with only passing the string itself. Period

asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)     'mov bx,[bp+06]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H57) + CHR$(&H2)     'mov dx,[bx+2] get sadd
asm$ = asm$ + CHR$(&HB4) + CHR$(&H9)                  'mov ah,9 ds points already to stringseg
asm$ = asm$ + CHR$(&HCD) + CHR$(&H21)                 'int 21
asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H2) + CHR$(&H0)      'retf 8
dosprn$ = asm$
END FUNCTION

DEFINT A-Z
SUB fixedstringinfo
'-------------------------------------------------
'This function checks how fixed strings are passed
'through a call absolute procedure
'-------------------------------------------------
asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)     'mov bx,[bp+06]
asm$ = asm$ + CHR$(&H89) + CHR$(&HD9)                 'mov cx,bx     get varptr
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7)                  'mov ax,[bx]   get len
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)     'mov bx,[bp+0A] first var
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)                  'mov [bx],ax
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+08] sec var
asm$ = asm$ + CHR$(&H89) + CHR$(&HF)                  'mov [bx],cx

asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H6) + CHR$(&H0)      'retf 6

DIM als AS STRING * 31
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(a, b, als$, Codeoff)
'________________________________________
DEF SEG
COLOR 0, 7: PRINT "FIXED STRING PASSING INFORMATION": COLOR 7, 0: PRINT :
COLOR 0, 7: PRINT "Fixed String passed to the stack as a$":
PRINT "CALL ABSOLUTE (a,b,a$,codeoff)"
COLOR 7, 0: PRINT "BX is initialized as BX = [BP+06]"
PRINT "After that:"
PRINT "First variabele( Length of string at [BX])       : "; a
PRINT "Second variabele( 'VARPTR' of string at BX)<NOT> : "; HEX$(b)
PRINT "The control values of LEN and VARPTR are         :"; : COLOR 0, 7:
PRINT LEN(als$); " "; HEX$(VARPTR(als$)); "  ";
COLOR 7, 0


END SUB

SUB intarrayinfo
'-------------------------------------------------------
'This sub does nothing more then change an array!
'SI and DI are used since they are basedisplacement for
'DS where BP is basedisplacement for SS!
'-------------------------------------------------------

DIM a(1, 1): segje = VARSEG(a(0, 0)): offje = VARPTR(a(0, 0))
COLOR 0, 7: PRINT "Array passing information "; : COLOR 7, 0: PRINT :
PRINT "The array as initialized:"
FOR j = 0 TO 1: FOR I = 0 TO 1:
  a(I, j) = I * 10 + j:
  PRINT "element :"; j; ","; I; "value :"; a(I, j):
NEXT: NEXT

asm$ = ""
asm$ = asm$ + CHR$(&H55)                          'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)             'mov bp,sp
asm$ = asm$ + CHR$(&H1E)                          'push ds
'---------------------------------
'Get si to point to offset array:
'---------------------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6) 'mov bx,[bp+06]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H37)             'mov si,[bx]
'-----------------------
'segment of array to ds:
'----------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8) 'mov bx,[bp+08]
asm$ = asm$ + CHR$(&H8E) + CHR$(&H1F)             'mov ds,[bx]
'-------------------------------------
'Increment first element and store it:
'-------------------------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H3C)             'mov di,[si]
asm$ = asm$ + CHR$(&H47)                          'inc di
asm$ = asm$ + CHR$(&H89) + CHR$(&H3C)             'mov [si],di
'--------------------------------------
'Decrement second element and store it:
'--------------------------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7C) + CHR$(&H2) 'mov di,[si+2]
asm$ = asm$ + CHR$(&H4F)                          'dec di
asm$ = asm$ + CHR$(&H89) + CHR$(&H7C) + CHR$(&H2) 'mov [si+2],di

asm$ = asm$ + CHR$(&H1F)                          'pop ds
asm$ = asm$ + CHR$(&H5D)                          'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H4) + CHR$(&H0)  'retf 4
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(segje, offje, Codeoff)
'________________________________________
DEF SEG

PRINT "The array after machinations: increment first/decrement second element"
FOR j = 0 TO 1: FOR I = 0 TO 1:
  PRINT "element :"; j; ","; I; "value :"; a(I, j):
NEXT: NEXT



END SUB

SUB intarrayinfo2
'---------------------------------------------------------
'This sub does nothing more then get elements of an array
'---------------------------------------------------------

DIM a(1, 1):
FOR j = 0 TO 1: FOR I = 0 TO 1:
  a(I, j) = I * 10 + j + 1:
NEXT: NEXT
segje = VARSEG(a(0, 0)): offje = VARPTR(a(0, 0))

asm$ = ""
asm$ = asm$ + CHR$(&H55)                          'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)             'mov bp,sp
asm$ = asm$ + CHR$(&H1E)                          'push ds
'---------------------------------
'Get si to point to offset array:
'---------------------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6) 'mov bx,[bp+06]
asm$ = asm$ + CHR$(&HC5) + CHR$(&H37)             'lds si,[bx]    get ptr to array
asm$ = asm$ + CHR$(&H8C) + CHR$(&HD8)             'mov ax,ds      and saving
asm$ = asm$ + CHR$(&H8B) + CHR$(&H4C) + CHR$(4)   'mov cx,[si+04] get an arrayelement
                                                                  'third element!
asm$ = asm$ + CHR$(&H1F)                          'pop ds
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8) 'mov bx,[bp+08] last var
asm$ = asm$ + CHR$(&H89) + CHR$(&HF)              'mov [bx],cx
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA) 'mov bx,[bp+0a]  sec var
asm$ = asm$ + CHR$(&H89) + CHR$(&H37)             'mov [bx],si
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC) 'mov bx,[bp+08] first var
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)              'mov [bx],ax

asm$ = asm$ + CHR$(&H5D)                          'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H8) + CHR$(&H0)  'retf 8
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(b, c, d, a(), Codeoff)
'________________________________________
DEF SEG
PRINT
COLOR 0, 7: PRINT "Original array passed to the stack as array a()":
PRINT "CALL ABSOLUTE (b,c,d,a(),codeoff)"
COLOR 7, 0: PRINT "BX is initialized as BX = [BP+06]"
PRINT "After that:"
PRINT "First variabele( segment of array at [BX+2])                 : "; HEX$(b)
PRINT "Second variabele( offset of array at [BX])                   : "; HEX$(c)
PRINT "Third variabele (value of element at [BX+2]:[BX+2*elementnr] :"; d
PRINT "The control values are resp.: "; : COLOR 0, 7:
PRINT HEX$(segje), HEX$(offje), a(0, 1); : COLOR 7, 0


END SUB

SUB integerinfo
'--------------------------------------------------------------
'This function checks how integers are passed to call absolute
'First by reference and then by value..
'--------------------------------------------------------------
asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H76) + CHR$(&H6)     'mov si,[bp+06]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H4)                  'mov ax,[si]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+08]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H1F)                 'mov bx,[bx]
asm$ = asm$ + CHR$(&H89) + CHR$(&H1C)                 'mov [si],bx
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)     'mov bx,[bp+0a]
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)                  'mov [bx],ax
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+08]
asm$ = asm$ + CHR$(&H89) + CHR$(&H37)                 'mov [bx],si
asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H6) + CHR$(&H0)      'retf 6
'______________________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$): fill = 76: in = 5: ints = in
CALL absolute(a, fill, ints, Codeoff)
'_______________________________________________________
DEF SEG
COLOR 0, 7: PRINT "INTEGER PASSING INFORMATION"; : COLOR 7, 0: PRINT : PRINT
COLOR 0, 7: PRINT "Integer passed to the stack by reference as ints":
PRINT "CALL ABSOLUTE (a,fill,ints,codeoff)"
COLOR 7, 0: PRINT "BX is intialized as BX =[SP+6]"
PRINT "After that:"
PRINT "First variabele( Value of ints at [BX])         : "; HEX$(a)
PRINT "Second variabele( Varptr of ints at BX)         : "; HEX$(fill)
PRINT "We changed the ints to fill                     : "; HEX$(ints)
PRINT "The control values VARPTR and value are         : "; : COLOR 0, 7:
PRINT HEX$(VARPTR(ints)), HEX$(in): COLOR 7, 0

'And lets do it by value...

asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H46) + CHR$(&H6)     'mov ax,[bp+06]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+0A]
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)                  'mov [bx],ax
asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H4) + CHR$(&H0)      'retf 4

'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$): ints = 8
CALL absolute(ax, BYVAL (ints), Codeoff)
'________________________________________
DEF SEG
PRINT
COLOR 0, 7: PRINT "Integer passed to the stack by value as BYVAL(ints)":
PRINT "CALL ABSOLUTE (AX,BYVAL(ints),codeoff)"
COLOR 7, 0: PRINT "AX is intialized as AX=[SP+6]"
PRINT "After that:"
PRINT "First variabele( Value of ints at AX )          : "; HEX$(ax)
PRINT "The control value of ints is                    : "; : COLOR 0, 7:
PRINT HEX$(ints): COLOR 7, 0

END SUB

SUB longarrayinfo
'---------------------------------------------------------
'This sub does nothing more then get elements of a
'array of long integers
'---------------------------------------------------------
COLOR 0, 7: PRINT "LONG INTEGER ARRAY passing information "; : COLOR 7, 0: PRINT :
DIM a&(1, 1):
FOR j = 0 TO 1: FOR I = 0 TO 1:
  a&(I, j) = &HFFFFF + I * 10 + j + 1:
NEXT: NEXT
segje = VARSEG(a&(0, 0)): offje = VARPTR(a&(0, 0))

asm$ = ""
asm$ = asm$ + CHR$(&H55)                          'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)             'mov bp,sp
asm$ = asm$ + CHR$(&H1E)                          'push ds
'---------------------------------
'Get si to point to offset array:
'---------------------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6) 'mov bx,[bp+06]
asm$ = asm$ + CHR$(&HC5) + CHR$(&H37)             'lds si,[bx]    get ptr to array
asm$ = asm$ + CHR$(&H8C) + CHR$(&HD8)             'mov ax,ds      and saving
asm$ = asm$ + CHR$(&H66) + CHR$(&H8B) + CHR$(&H4C) + CHR$(8)'mov ecx,[si+08]get an arrayelement
                                                                  'third element!
asm$ = asm$ + CHR$(&H1F)                          'pop ds
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8) 'mov bx,[bp+08] last var
asm$ = asm$ + CHR$(&H66) + CHR$(&H89) + CHR$(&HF) 'mov [bx],ecx
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA) 'mov bx,[bp+0a]  sec var
asm$ = asm$ + CHR$(&H89) + CHR$(&H37)             'mov [bx],si
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC) 'mov bx,[bp+08] first var
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)              'mov [bx],ax

asm$ = asm$ + CHR$(&H5D)                          'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H8) + CHR$(&H0)  'retf 8
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(b, c, d&, a&(), Codeoff)
'________________________________________
DEF SEG
PRINT
COLOR 0, 7: PRINT "Original array passed to the stack as array a&()":
PRINT "CALL ABSOLUTE (b,c,d&,a&(),codeoff)"
COLOR 7, 0: PRINT "BX is initialized as BX = [BP+06]"
PRINT "After that:"
PRINT "First variabele( segment of array at [BX+2])                 : "; HEX$(b)
PRINT "Second variabele( offset of array at [BX])                   : "; HEX$(c)
PRINT "Third variabele (value of element at [BX+2]:[BX+4*elementnr] :"; d&
PRINT "The control values are resp.: "; : COLOR 0, 7:
PRINT HEX$(segje), HEX$(offje), a&(0, 1); : COLOR 7, 0

END SUB

SUB longinfo (longs&)
'------------------------------------------------------------
'This function checks how longs are passed to call absolute
'First by reference and then by value..
'------------------------------------------------------------
asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)     'mov bx,[bp+06]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7)                  'mov ax,[bx]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H4F) + CHR$(&H2)     'mov cx,[bx+2]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+08]
asm$ = asm$ + CHR$(&H89) + CHR$(&HF)                  'mov [bx],cx
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)     'mov bx,[bp+0a]
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)                  'mov [bx],ax
asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H6) + CHR$(&H0)      'retf 6
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(a, b, longs&, Codeoff)
'________________________________________
DEF SEG
COLOR 0, 7: PRINT "LONG INTEGER PASSING INFORMATION": COLOR 7, 0: PRINT :
COLOR 0, 7: PRINT "Long integer passed to the stack by reference as longs&":
PRINT "CALL ABSOLUTE (a,b,longs&,codeoff)"
COLOR 7, 0: PRINT "BX is initialized as BX = [BP+06]"
PRINT "After that:"
PRINT "First variabele( Lowword of long at [BX])        : "; HEX$(a)
PRINT "Second variabele( Highword of array at [BX+2])   : "; HEX$(b)
PRINT "The control value of the long integer is:        : "; : COLOR 0, 7:
PRINT HEX$(longs&): COLOR 7, 0

'And lets do it by value...

asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H46) + CHR$(&H6)     'mov ax,[bp+06]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H4E) + CHR$(&H8)     'mov cx,[bp+08]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)     'mov bx,[bp+08]
asm$ = asm$ + CHR$(&H89) + CHR$(&HF)                  'mov [bx],cx
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC)     'mov bx,[bp+0a]
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)                  'mov [bx],ax
asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H8) + CHR$(&H0)      'retf 8
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(a, b, BYVAL (longs&), Codeoff)
'________________________________________
DEF SEG
PRINT
COLOR 0, 7: PRINT "Long integer passed by value to the stack as longs&":
PRINT "CALL ABSOLUTE (a,b,longs&,codeoff)"
COLOR 7, 0: PRINT "BP is initialized as BP = SP"
PRINT "After that:"
PRINT "First variabele( Lowword of long at [BP+06])     : "; HEX$(a)
PRINT "Second variabele( Highword of array at [BP+08])  : "; HEX$(b)
PRINT "The control value of the long integer is:        : "; : COLOR 0, 7:
PRINT HEX$(longs&): COLOR 7, 0

END SUB

SUB movearr2arr

'Wat this function does is something that you need surprisingly
'often. When you take a good look at some interruptlist you
'will notice some difficult parameterblocks there that you have
'to pass to the interrupt. Often those parameterblocks are
'discontinue( if that is the right word) in that they consist
'of bytes,words and dubbel words. That is why this function
'might be extremely useful for loading up some parameterblock
'This is just an example of loading up a parameterblock
'with: DW  length is a long
'      W   handle is an integer
'      DW  offset:segment of array
'      W   handle is an integer
'      DW  32 bit offset is a long
'--actually this is the syntax for XMS.move( just to let you know it)
'You should notice that the uploading of elements is redundant, and that
'is the reason why some large sorting algorithm can be quite small in
'asm source!. Also notice that we never used DS[si] so far since there
'where no strings to pass to the params!


'STACKPASSING nrbytes&,XMShandle,source(),XMSoffset,Params()
'IN        : ES[DI] parameterblock
'            ....   parameters to pass to the block
             'nrbytes&
             'XMShandle
             'sourcearray
             'XMSoffset&
'OUT       : ES[DI] filled parameterblock

'USING IN QBASIC: ARRAYPASSING, "ALL TYPES" PASSING
'-------------------------------------------------------------

asm$ = ""
asm$ = asm$ + CHR$(&H55)                          'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)             'mov bp,sp
asm$ = asm$ + CHR$(&H6)                           'push Es
'----------------------------------------
'Let us first put the destiny in ES[DI]:
'----------------------------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6) 'mov bx,[bp+06]
asm$ = asm$ + CHR$(&HC4) + CHR$(&H3F)             'LES DI,[bx]  get ptr to array
'------------
'Get nrbytes&
'-------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HE) 'mov bx,[bp+0e]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7)              'mov ax,[bx]
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]   lowbyte
asm$ = asm$ + CHR$(&H8B) + CHR$(&H47) + CHR$(&H2) 'mov ax,[bx+2]
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]   highbyte
'--------------------------
'Store 0 for source handle
'--------------------------
asm$ = asm$ + CHR$(&H31) + CHR$(&HC0)             'xor ax,ax
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]   0
'---------------------------------------
'Get offset and segment of source array
'---------------------------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA) 'mov bx,[bp+0A]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7)              'mov ax,[bx]  get OFFSRC
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H47) + CHR$(&H2) 'mov ax,[bx+2] get SEGSRC
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]
'-----------------
'Get XMS handle
'-----------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC) 'mov bx,[bp+0C]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7)              'mov ax,[bx]  get handle
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]
'----------------------
'Get XMS 32 bit offset
'----------------------
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8) 'mov bx,[bp+08]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7)              'mov ax,[bx]
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]   lowbyte
asm$ = asm$ + CHR$(&H8B) + CHR$(&H47) + CHR$(&H2) 'mov ax,[bx+2]
asm$ = asm$ + CHR$(&HAB)                          'stosw naar es[di]   highbyte
'--------------------------------------------------
'Well in fact we are done. Here is where the real
'XMS thing starts..but thats for later
'--------------------------------------------------
asm$ = asm$ + CHR$(&H7)                           'push Es
asm$ = asm$ + CHR$(&H5D)                          'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&HA) + CHR$(&H0)  'retf a


nrbytes& = &HF1234567: DIM src(10000): xmsoff& = &HFEDCBA98
DIM params(7): xmshandle = &H1122
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(nrbytes&, xmshandle, src(), xmsoff&, params(), Codeoff)
'________________________________________

COLOR 0, 7: PRINT "ARRAY MOVE DEMONSTRATION": COLOR 7, 0: PRINT :

COLOR 0, 7
FOR I = 0 TO 7: PRINT I, HEX$(params(I)): NEXT
COLOR 7, 0
PRINT "There was passed a:"
COLOR 0, 7: PRINT "CALL ABSOLUTE(nrbytes&, xmshandle, src(), xmsoff&, params(), Codeoff) "
COLOR 7, 0: PRINT "Controlvalues are:": COLOR 0, 7
PRINT "0  DW  Nrbytes   : "; HEX$(nrbytes&)
PRINT "2  W handle      :"; 0
PRINT "3  W offset src  : "; HEX$(VARPTR(src(0)))
PRINT "4  W segment src : "; HEX$(VARSEG(src(0)))
PRINT "5  W XMShandle   : "; HEX$(xmshandle)
PRINT "6  DW XMSoffset  : "; HEX$(xmsoff&)
COLOR 7, 0
END SUB

SUB stringarrayinfo
'--------------------------------------------------
'This function checks how string array's are passed
'through a call absolute procedure
'--------------------------------------------------
asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)     'mov bx,[bp+06]
asm$ = asm$ + CHR$(&H8B) + CHR$(&H57) + CHR$(&H2)     'mov dx,[bx+2] get seg
asm$ = asm$ + CHR$(&H8B) + CHR$(&H37)                 'mov si,[bx]   get varptr

asm$ = asm$ + CHR$(&H8B) + CHR$(&HC)                  'mov cx,[si]   get len first element
asm$ = asm$ + CHR$(&H8B) + CHR$(&H44) + CHR$(&H2)     'mov ax,[si+2] get sadd first element

asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HE)     'mov bx,[bp+0E] first var
asm$ = asm$ + CHR$(&H89) + CHR$(&H17)                 'mov [bx],dx  seg
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC)     'mov bx,[bp+0C] sec var
asm$ = asm$ + CHR$(&H89) + CHR$(&H37)                 'mov [bx],si  varptr
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)     'mov bx,[bp+0A] third var
asm$ = asm$ + CHR$(&H89) + CHR$(&HF)                  'mov [bx],cx   len
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+08] fourth var
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)                  'mov [bx],ax   sadd

asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&HA) + CHR$(&H0)      'retf A


CLS : DIM arraystrings$(10)
arraystrings$(0) = "doei"
arraystrings$(1) = "b"
arraystrings$(2) = "En dit dan als ik vragen mag ?"

'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(a, b, c, d, arraystrings$(), Codeoff)
'________________________________________
DEF SEG
COLOR 0, 7: PRINT "STRINGARRAY PASSING INFORMATION": COLOR 7, 0: PRINT :
COLOR 0, 7: PRINT "String passed to the stack as arraystring$()":
PRINT "CALL ABSOLUTE (a,b,c,d,arraystrings$(),codeoff)"
COLOR 7, 0: PRINT "BX is initialized as BX = [BP+06]"
PRINT "After that:"
PRINT "First variabele(  VARSEG of stringsarray at [BX+2] )      : "; HEX$(a)
PRINT "Second variabele( VARPTR of stringsarray at [BX])         : "; HEX$(b)
PRINT "Third variabele( LEN of first string at   [VARPTR])       : "; HEX$(c)
PRINT "Fourth variabele( SADD of first string at [VARPTR+2])     : "; HEX$(d)
PRINT "The control values of SEG, VARPTR, LEN and SADD are       : "; : COLOR 0, 7:
PRINT HEX$(VARSEG(arraystrings$(0))); " "; HEX$(VARPTR(arraystrings$(0))); " "; HEX$(LEN(arraystrings$(0))); " "; HEX$(SADD(arraystrings$(0)))
COLOR 7, 0



END SUB

SUB stringinfo (a$)
'---------------------------------------------
'This function checks how strings are passed
'through a call absolute procedure
'-------------------------------------------
asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)     'mov bx,[bp+06]
asm$ = asm$ + CHR$(&H89) + CHR$(&HD9)                 'mov cx,bx     get varptr
asm$ = asm$ + CHR$(&H8B) + CHR$(&H7)                  'mov ax,[bx]   get len
asm$ = asm$ + CHR$(&H8B) + CHR$(&H57) + CHR$(&H2)     'mov dx,[bx+2] get sadd
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC)     'mov bx,[bp+0c] first var
asm$ = asm$ + CHR$(&H89) + CHR$(&H7)                  'mov [bx],ax
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)     'mov bx,[bp+0a] sec var
asm$ = asm$ + CHR$(&H89) + CHR$(&HF)                  'mov [bx],cx
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+08] third var
asm$ = asm$ + CHR$(&H89) + CHR$(&H17)                 'mov [bx],dx

asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H8) + CHR$(&H0)      'retf 8
'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(a, b, c, a$, Codeoff)
'________________________________________
DEF SEG
COLOR 0, 7: PRINT "STRING PASSING INFORMATION": COLOR 7, 0: PRINT :
COLOR 0, 7: PRINT "String passed to the stack as a$":
PRINT "CALL ABSOLUTE (a,b,c,a$,codeoff)"
COLOR 7, 0: PRINT "BX is initialized as BX = [BP+06]"
PRINT "After that:"
PRINT "First variabele( Length of string at [BX]  )     : "; a
PRINT "Second variabele( VARPTR of string at BX)        : "; HEX$(b)
PRINT "Second variabele( SADD of string at [BX+2])      : "; HEX$(c)
PRINT "The control values of LEN, VARPTR and SADD are   :"; : COLOR 0, 7:
PRINT LEN(a$); " "; HEX$(VARPTR(a$)); "  "; HEX$(SADD(a$))
COLOR 7, 0

END SUB

SUB swapstringarray
'----------------------------------------------------------------
'This procedure will swap some elements of a stringarray.
'Very useful when you want a fast sort of stringelements.

'The better method then the one used here for an array of
'fixed length strings is to sort the stringdescriptors. That way
'you only need to copy the strings one time. However QBASIC seems
'to prevent the straightforward updating of the descriptors.
'What IS possible is to pass an index (integerarray) along with
'the array of strings and 'sort' the indexarray.
'----------------------------------------------------------------

asm$ = ""
asm$ = asm$ + CHR$(&H55)                         'push bp        4
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)            'mov bp,sp      1
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)'mov bx,[bp+06] 1+9
asm$ = asm$ + CHR$(&H8B) + CHR$(&H1F)            'mov bx,[bx]   get varptr  1+5
asm$ = asm$ + CHR$(&HBE) + MKI$(&HA)             'mov si,a       1
asm$ = asm$ + CHR$(&H8B) + CHR$(&H28)            'mov bp,[bx+si]ptr sadd 3d element  1+7
asm$ = asm$ + CHR$(&HBE) + MKI$(&H2)             'mov si,2       1
asm$ = asm$ + CHR$(&H8B) + CHR$(&H18)            'mov bx,[bx+si]ptr sadd 1st element  1+7
asm$ = asm$ + CHR$(&HBE) + MKI$(&H8)             'mov si,A bytes to copy   1
asm$ = asm$ + CHR$(&H8B) + CHR$(&H0)             'mov al,[bx+si] get first element first 2 char 1+7
asm$ = asm$ + CHR$(&H87) + CHR$(&H2)             'xchg al,[bp+si]xchg with third element  3+7
asm$ = asm$ + CHR$(&H89) + CHR$(&H0)             'mov [bx+si],al 1+7
asm$ = asm$ + CHR$(&H83) + CHR$(&HEE) + CHR$(2)  'sub si,2       1
asm$ = asm$ + CHR$(&H79) + CHR$(&HF5)            'jns - 11       3/1

asm$ = asm$ + CHR$(&H5D)                         'pop bp         4
asm$ = asm$ + CHR$(&HCA) + CHR$(&H2) + CHR$(&H0) 'retf 2         14


CLS : DIM arraystrings$(2)
arraystrings$(0) = "doei" + SPACE$(7)
arraystrings$(1) = "b" + SPACE$(9)
arraystrings$(2) = "En dit dan"
COLOR 0, 7: PRINT "STRINGARRAY SWAPPING DEMONSTRATION": COLOR 7, 0: PRINT :
PRINT :
COLOR 0, 7: PRINT "ARRAY BEFORE SWAP": COLOR 7, 0
FOR I = 0 TO 2
  PRINT I; ":", arraystrings$(I)
NEXT

'________________________________________
Codeoff = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(arraystrings$(), Codeoff)
'________________________________________
DEF SEG : PRINT
COLOR 0, 7: PRINT "ARRAY AFTER SWAP": COLOR 7, 0
FOR I = 0 TO 2
  PRINT I; ":", arraystrings$(I)
NEXT

'
END SUB

DEFSNG A-Z
SUB typeinfo
'---------------------------------------------
'This function checks how types are passed
'through a call absolute procedure
'-------------------------------------------
asm$ = ""
asm$ = asm$ + CHR$(&H55)                              'push bp
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)                 'mov bp,sp
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)     'mov bx,[bp+06]
asm$ = asm$ + CHR$(&H66) + CHR$(&H8B) + CHR$(&H7)     'mov eax,[bx]  get string
asm$ = asm$ + CHR$(&H8B) + CHR$(&H4F) + CHR$(5)       'mov cx,[bx+5] get int
asm$ = asm$ + CHR$(&H66) + CHR$(&H8B) + CHR$(&H57) + CHR$(7)'mov edx,[bx+7] get long
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC)     'mov bx,[bp+0c] first var
asm$ = asm$ + CHR$(&H66) + CHR$(&H89) + CHR$(&H7)     'mov [bx],eax
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA)     'mov bx,[bp+0a] sec var
asm$ = asm$ + CHR$(&H89) + CHR$(&HF)                  'mov [bx],cx
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8)     'mov bx,[bp+08] third var
asm$ = asm$ + CHR$(&H66) + CHR$(&H89) + CHR$(&H17)    'mov [bx],edx

asm$ = asm$ + CHR$(&H5D)                              'pop bp
asm$ = asm$ + CHR$(&HCA) + CHR$(&H8) + CHR$(&H0)      'retf 8
'________________________________________
Codeoff% = SADD(asm$)
DEF SEG = VARSEG(asm$)
CALL absolute(a&, b%, c&, test, Codeoff%)
'________________________________________
DEF SEG
COLOR 0, 7: PRINT "TYPE PASSING INFORMATION": COLOR 7, 0: PRINT :
COLOR 0, 7: PRINT "TYPE passed to the stack as test:"
PRINT "CALL ABSOLUTE (a&,b%,c&,test,codeoff%)"
COLOR 7, 0: PRINT "BX is initialized as BX = [BP+06]"
PRINT "After that:"
PRINT "First variable (MKL-ed string at [BX]) : "; MKL$(a&)
PRINT "Second variable(integer at [BX+5])     : "; HEX$(b%)
PRINT "Third variabele( long at [BX+7])       : "; HEX$(c&)
PRINT "The control values of string, int and long are   :"; : COLOR 0, 7:
PRINT test.astring; " "; HEX$(test.ainteger); "  "; HEX$(test.along)
COLOR 7, 0


END SUB
