Calling .asm from QB 4.5 and sending text-strings 
Author Message
 Calling .asm from QB 4.5 and sending text-strings


MR> I want to call a .asm subroutine from a QuickBasic 4.5 program..
  > i want to send some text strings to the .asm routine, and then get
  > some other textstrings back..  this is how i do it now:

MR> DECLARE SUB xxx(SEG string1$, SEG string2$, SEG string3$)
  > CALLS xxx(string1$, string2$, string3$)

MR> ..now, how do i get the .asm program to find them? its something
  > with [bp+6] or something, but i dont remember.. and how do i send
  > the strings back, (3 completley diffrent strings..).. any textfiles
  > or anything, or anyone who can explain it?

Well this is rather a tall order for e-mail so perhaps the best thing
I can do is give you some of the standard code I use for finding and
returning strings passed between QuickBASIC and Assembler.

To begin with you don't need the SEG clause in your DECLARE statement.
Just naming a string causes a near pointer to its descriptor to be passed
to the routine and is enough to enable you to find it. This string
descriptor, in QuickBASIC, is a four-byte structure containing the string
length (0-32767) in its first two bytes. The second two bytes hold a
near pointer to the offset of the actual string data in DGROUP, the
default Data segment.

STRINGS.ASM below is a standard module that I link to all my programs
that use assembly-language routines for string processing. I assembled
it with Microsoft's MASM 6.11a, but it should be easy to adapt to
TASM or whichever assembler you use.

--- cut here ---------------------------------------------------------------
; STRINGS.ASM   this module incorporates a number of string-manipulation
;               routines
;
;   Author:     Christy Gemmell
;   For:        Assembly-Language Toolbox
;   Version:    5.58
;   Date:       2/12/1994
;
                .model  medium

                extrn   B$STRI:proc             ; BASIC's STRING$ function
                extrn   B$RTRM:proc             ; BASIC's RTRIM() function

                public  _FindString
                public  _MakeString

                .code

;   Find the address and length of a string passed from QuickBASIC.
;
;   Call with:  AX    = string descriptor
;
;   Returns:    ES:DI = address of BASIC string
;               CX    = length of string
;
_FindString     proc    far
                push    ds                      ; Save these registers
                push    ax
                push    bx
                push    dx
                push    ss                      ; Force
                pop     ds                      ;    DGROUP
                mov     bx,ax                   ; Descriptor to BX
                mov     cx,[bx]                 ; Length to CX
                push    ds                      ; Align DGROUP with
                pop     es                      ;    the Extra segment
                mov     di,[bx+2]               ; ES:DI==> target string
                pop     dx                      ; Clean up the stack
                pop     bx
                pop     ax
                pop     ds
                ret                             ; Return to caller
_FindString     endp

;   Create a BASIC string and fills it with data specified.
;
;   Call with:  CX    = length of source data
;               DS:SI = address of data to fill string with
;
;   Returns:    AX    = string descriptor (for passing back to BASIC)
;
_MakeString     proc    far
                push    es                      ; Save these registers
                push    ds
                push    di
                push    si
                push    bx
                push    cx
                push    dx
                push    ds                      ; Preserve source segment
                push    ss                      ; Force
                pop     ds                      ;    DGROUP
                push    cx                      ; Push string length
                mov     ax,20h                  ; Specify blank spaces
                push    ax                      ; Ask BASIC to
                call    B$STRI                  ;    create a string
                mov     bx,ax                   ; Descriptor to BX
                mov     cx,[bx]                 ; Length to CX
                push    ds                      ; Align DGROUP with
                pop     es                      ;    the Extra segment
                mov     di,[bx+2]               ; ES:DI==> target string
                mov     dx,ax                   ; Preserve target descriptor
                pop     ds                      ; DS:SI==> source buffer
                rep     movsb                   ; Copy source to target
                push    ss                      ; Force DGROUP
                pop     ds                      ;    again
                mov     ax,dx                   ; Descriptor to AX
                push    ax                      ; Ask BASIC to
(Continued to next message)

 * 1st 2.00o #323 * Father forgive me, for I have GOTOed.



Fri, 05 Dec 1997 03:00:00 GMT  
 Calling .asm from QB 4.5 and sending text-strings
(Continued from previous message)
                call    B$RTRM                  ;    trim the string
                pop     dx                      ; Clean up the stack
                pop     cx
                pop     bx
                pop     si
                pop     di
                pop     ds
                pop     es
                ret                             ; Return to caller
_MakeString     endp

                end
--- and here ---------------------------------------------------------------

Here is an example program which calls _FindString to obtain the string
argument passed to it from QuickBASIC.

DRIVETHERE

Detects if a logical drive is present in the system.

DECLARE FUNCTION DriveThere% (Drive$)

Drive$ is the letter of the diskette drive to be tested and can be
anything from A: to Z: (you can omit the colon).

the function returns -1 (logical TRUE) if the drive is present or zero
(logical FALSE) if it does not exist.

--- cut here ---------------------------------------------------------------
; DRVTHERE.ASM  test if a specified drive exists in the system.
;
;   Author:     Christy Gemmell
;   For:        Assembly-Language Toolbox
;   Version:    5.58
;   Date:       6/2/1995
;
               .model   medium

                extrn   _FindString: proc

                public  DriveThere

               .code

DriveThere      proc    far
                push    bp                      ; Save Base pointer
                mov     bp,sp                   ; Establish stack frame
                push    ds                      ; Save Data segment
                mov     ax,[bp+6]               ; Get drive letter
                call    _FindString             ; Find out all about it
                xor     ax,ax                   ; Assume the worst
                jcxz    There_2                 ; Abort if a null string
                mov     dl,es:[di]              ; Get drive letter
                and     dl,11011111b            ; Force it to uppercase
                sub     dl,64                   ; Convert to numeric
                mov     ah,32h                  ; DOS Service 50
                int     21h                     ;  - get drive parameters
                or      al,al                   ; Did it work?
                jz      There_1                 ; Branch if so
                xor     ax,ax                   ; Else report that the
                jmp     short There_2           ;    drive doesn't exist
There_1:
                mov     ax,-1                   ; Report drive exists
There_2:
                pop     ds                      ; Clean up the stack
                pop     bp
                ret     2                       ; Return to QuickBASIC
DriveThere      endp

                end
--- and here ---------------------------------------------------------------

Returning a string as the output of a function is a little bit more
difficult since what QuickBASIC expects is, once again, a near pointer
to the string descriptor returned in the AX register.

What I do is use QuickBASIC itself to create the string for me via a
call to its built-in function B$STRI. B$STRI is equivalent to STRING$
since it lets you specify the length of the string to be created in
CX and a default character it should be filled with in AX (I use blank
spaces). _MakeString (above) handles this for you. After the call to
B$STRI the pointer to the string descriptor is returned in AX.

Once the string is created the appropriate data needs to be copied
to it. To cater for those cases where this data is insufficient to
fill the string I then use another built-in function B$RTRM (the
equivalent of RTRIM$) to trim off any trailing spaces before it is
returned to QuickBASIC.

Here is another example program to show how you can use _MakeString.

BOOTDRIVE

Determines the drive from which the system was booted.

DECLARE FUNCTION BootDrive$ ()

The drive letter returned includes the colon (eg "C:").

--- cut here ---------------------------------------------------------------
; BOOTDRV.ASM   Determine the drive that DOS booted from.
;               (only valid with DOS 4.0 and later)
;
;   Author:     Christy Gemmell
;   For:        Assembly-Language Toolbox
;   Version:    5.58
;   Date:       6/2/1995
;
               .model   medium

                extrn   _MakeString: proc

                public  BootDrive

               .code

Letter          db      ' :'

BootDrive       proc    far
                push    ds                      ; Preserve
                push    es                      ;    these
                push    si                      ;      registers
                push    cs                      ; Align Code and
                pop     ds                      ;    Data segments
(Continued to next message)

 * 1st 2.00o #323 * Father forgive me, for I have GOTOed.



Fri, 05 Dec 1997 03:00:00 GMT  
 Calling .asm from QB 4.5 and sending text-strings
(Continued from previous message)
                mov     ah,52h                  ; DOS Service 82
                int     21h                     ;  - get list of lists
                mov     al,es:[bx+43h]          ; Get boot drive number
                add     al,64                   ; Convert to ASCII
                mov     si,offset Letter        ; DS:SI==> return string
                mov     [si],al                 ; Stuff the drive letter
                mov     cx,2                    ; include the colon
                call    _MakeString             ; Convert to BASIC string
                pop     si                      ; Clean up the stack
                pop     es
                pop     ds
                ret                             ; Return to caller
BootDrive       endp

                end
--- and here ---------------------------------------------------------------

I see, however, that you want to return *three* new strings to
QuickBASIC which makes things more difficult since a function can
only return one argument, be it string or numeric. What I think
you'll have to do is pass two extra dummy strings to the routine
and copy the additional data into these. Since strings are passed
by reference, any changes your routine makes to them will be passed
back to the original program when you return to it.

I'm sorry I can't go into more detail... this message is long
enough already. Hopefully its enough to get you started, but if
you want more help please e-mail me.

MR> please send a copy of your answer by mail, since our news-server
  > is a bit strange right now...

I did send this by e-mail but it bounced with an 'Invalid Local User'
message. However I think this may be the fault of my service rather
than yours since I've had a few of those lately.

+------------------------+-----------------------------------------------+
|     _/_/_/_/  _/_/_/_/ | Christy Gemmell, Singular Software            |
|    _/        _/        | 11 Abingdon Road, Leicester LE2 1HA, England. |


| _/_/_/_/  _/_/_/_/     | Phone: +44-0116-254-7681                      |
+------------------------+-----------------------------------------------+

 * 1st 2.00o #323 * Father forgive me, for I have GOTOed.



Fri, 05 Dec 1997 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. QB 4.5 and .asm 2

2. QB 4.5 and .asm

3. "String Space Corrupt" in QB 4.5

4. QB 4.5 and CALL ABSOLUTE

5. QB 4.5 Call Absolute Prob

6. QB 4.5 Call Absolute Problem

7. CALL ABSOLETE() DOESN"T WORK IN QB 4.5

8. CALLING A QB 4.5 PROGRAM by phone?...

9. Rotating text in QB 4.5

10. Code for a Text-editor in QB 4.5

11. QB 4.0 Docs/QB 4.5 Wanted

12. want QB 4.5 QB 7.1 FOR FREE!!!

 

 
Powered by phpBB® Forum Software