Passing Parameters from an Assembly Language Routine

Published ByDateVersionKnowledge LevelKeywords
Revelation Technologies14 FEB 19891.1XEXPERTASM.DATE, ASM.TEST, INTERFACE

Calling assembly language routines from the Revelation environment offers the developer several advantages over using R/BASIC alone. Assembly language subroutines provide the following:

  • speed, especially for mathematical computations (but not necessarily for character (string) manipulation)
  • direct access to the operating system (DOS), such as to execute DOS interrupts
  • direct access to the hardware of the machine, such as communications devices, CD-ROM, etc.

However, using assembly language routines is slightly more complex than calling subroutines or functions written in R/BASIC. This bulletin addresses the issue of passing parameters (specific or varying in number) between R/BASIC programs and assembly language subroutines or functions.

Certain functions have been written into the AREV.EXE and REV.EXE that are callable from assembly language routines. These function calls provide the interface between the Revelation environment and assembly language routines.

Included in the Revelation assembly language interface are functions to input and output characters, set and query the Revelation environment (example: break key), allocate new string space, access operating system files, and as illustrated in this bulletin, pass parameters between the two environments.

When calling an assembly language subroutine from most other languages, including other assembly language programs, the parameters are usually passed by pushing and popping them onto and off the stack. To return a value from an assembly language function in non-Revelation environments, the return value is typically put into the DX:AX registers.

However, when calling an assembly language subroutine from R/BASIC, the parameters are passed instead through the use of one of the Revelation-specific function calls mentioned above. Specific Revelation functions exist that copy strings or numeric data between the assembly language routine and Revelation.

Like DOS interrupt calls, Revelation function calls are preceded by loading certain registers to determine which function is executed. The function call used to copy a value back to the Revelation environment differs (in other words, the AH register value differs) depending on the type of the data to be passed. One of the example programs in this bulletin, for instance, illustrates how the function 10H is used to copy a string from the assembly language routine to the Revelation environment. There are other functions for passing back integers, double integers, floating point numbers, etc.

Note: Some functions used in assembly language routines are only available in later versions of Advanced Revelation. See the documentation accompanying your assembly language interface for information on functions described here.

Figure 1 illustrates an assembly language function called ASM.TEST that has no arguments (is passed no values), but returns a string of characters. Although ASM.TEST will not receive any parameters, it must return a value to the calling program.

The function ASM.TEST is called from an R/BASIC program using syntax such as this:

DECLARE FUNCTION ASM.TEST
* call assembly function

VAR = ASM.TEST()

The program ASM.TEST allocates space for a variable through the function call 0FH (0FH is loaded into register AH). In this example, it allocates 11 bytes for the string hello world by putting 11 into the CX register.

The function call is made and the memory address for this variable is returned in the DI register. The routine saves this address on the stack to pass the string back to the calling program in a later function call. Then the routine puts the string hello world into memory. Here one can see how cumbersome it would be to do string handling in assembly language.

The ASM.TEST routine executes another function call to copy the string into the Revelation environment. This is done by putting 10H in the AH register to pass a string and 0 in the AL register for a non-dimensioned local variable. The starting address of the variable is restored to the DI register as well.

Notice that DX has a value of zero when this function call is made. This is because a variable is being assigned that was not passed to the routine. It is the variable on the left side of the assignment in the R/BASIC program – in this case, VAR. This is similar to a RETURN VAR in an R/BASIC function.

Figure 2 is an example of an R/BASIC program that calls an assembly language subroutine, ASM.DATE, to return the date and day of the week. Figure 3 is the source code of an assembly language routine called by the program illustrated in figure 2.

Although four parameters are passed to the routine by the R/BASIC program, they are not accessed by the assembly language subroutine (they are unassigned at this point). In this example there is no need to allocate space for the parameters, as the Revelation environment has already done so.

The first task the routine accomplishes is a DOS interrupt (this cannot be done in R/BASIC ) to get the system date. The subsequent Revelation function calls are done to pass back the results of the DOS interrupt. 12H is loaded into the AH register in order to pass an integer from the assembly language environment into the Revelation environment.

The CX register contains the integer. The AL register contains information about the type of variable being passed – in this case, a local non-dimensioned variable. Note that the DX register contains the number of the parameter in the parameter list being passed. Thus, 1 is in DX when passing the day, 2 for the month and so forth. In the routine ASM.TEST (above), DX contained 0, since the routine was a function that had no arguments.

There are Revelation functions that can be used in assembly language routines as the inverse of the examples used here. The examples used here pass data back to the calling program. There are similar functions to access the values passed to the assembly language routine.

Because Revelation cleans up the stack, there is no need for the ret 4 or ret 6 frequently used in other environments at the end of the assembly language routine's main procedure.

Calling an assembly language routine allows the possibility of passing varying number of parameters. To do this with an R/BASIC routine, one would have to pass a single variable and parse it using some character as a delimiter.

In an assembly language routine the number of parameters passed is in memory. The memory location is defined as a byte with the label no_args. By accessing this location, one can program the logic necessary to access the exact number of parameters passed.

For example, even though no_args is initialized to 0 in figure 3, it will acquire the value 4 during execution of the program in figure 2 because four parameters are passed. The same routine can be passed only three parameters, but the logic would have to be added so that the fourth parameter is not accessed in any way.

Note: The Revelation BBS ( 1-206-641-8110 up to 9600 baud, 8 bit, no parity, one stop ) has a variety of assembly language routines that are available to be downloaded. These routines are a mixture of object and source code so that assembly language programmers can look at the source code and non-assembly language programmers can run the object code.

The following tables list the functions used commonly to pass parameters between Revelation and Assembly Language subroutines.

Passing Parameters From Revelation To Assembly Language

Function                       Other
Call     Description           RegValues   Returned Values
0DH      Fetch string pointer  See note 2  DS:SI pointer to start of string
                                           CX length of string
                                           BP # of bytes that can be added
                                           without fetching more storage
11H      Fetch integer         See note 2  CX 16 bit integer
13H      Fetch long integer    See note 2  SI:CX 32 bit integer
1AH      Fetch temporary float See note 2  DS:SI pointer to 10-byte
                                           floating point number

Passing Parameters From Assembly Language To Revelation

Function                       Other
Call     Description           RegValues          Returned Values
0FH      Allocate space for    CX # bytes desired ES:DI pointer to start
         string storage                           of string
                                                  BP available bytes (<= to
                                                  # in CX due to paragraph
                                                  units)

10H      Pass string pointer   ES:DI pointer to start of string
                               CX length of the string
12H      Pass integer          CX 16 bit integer (see note 2)
14H      Pass long Integer     SI:CX 32 bit integer (see note 2)
1BH      Pass temporary Float  DS:SI pointer to a 10-byte
                               floating point number (see note 2)

Note 1: The double byte label no_args contains the number of parameters to be passed.

Note 2: DX register must be loaded with the ordinal number of the parameter passed (starting with one, not zero). AL register is loaded as follows:

AL High Nibble    Meaning
00B               non-dimensioned variable
01B               single dimension array (BX must equal element number)
10B               double dimension array (BX = row index, BP = column index)

AL Low Nibble     Meaning
00B               local variable
01B               COMMON variable

For example, a value of 1001B in AL indicates a 2 dimensional array in COMMON. (This value is listed incorrectly in the Assembly Language Interface Version 2.0 documentation.)

Note 3: Advanced Revelation 1.1 allows other function calls which are analogous to the ones above but use far pointers using the ES and DI registers.

;*********************************************************************
; Program ASM.TEST
;
; Written to be function called from a R/BASIC routine.
; Will return a string ('hello world') to the calling program.
; Will affect the ax,cx,es,di registers.
;
; Usage:
;
; variable = ASM.TEST()
;
; with ASM.TEST being this cataloged routine.
;
;*********************************************************************
cseg      segment     para public 'CODE'
          assume      cs:cseg
main      proc        far
          org         0                  ; start at address zero
          db          'ASSM'             ; 4-byte flag
          db          2                  ; identify as assembler routine
no_args   db          0                  ; number of arguments passed
no_coms   dw          0                  ; number of common variables
          dw          0                  ; unused
function  dd          0                  ; address for rev function calls
;*********************************************************************
;
; allocate space for return value
;
          mov         cx,11              ;no. of bytes
          mov         ah,0fh             ;function to allocate space
          call        function
          push        di                 ;for later function call
;
; move string, 'hello world' into memory
;
          mov         byte ptr es:[di],104 ;h
          inc         di
          mov         byte ptr es:[di],101 ;e
          inc         di
          mov         byte ptr es:[di],108 ;l
          inc         di
          mov         byte ptr es:[di],108 ;l
          inc         di
          mov         byte ptr es:[di],111 ;o
          inc         di
          mov         byte ptr es:[di],32 ;[space]
          inc         di
          mov         byte ptr es:[di],119 ;w
          inc         di
          mov         byte ptr es:[di],111 ;o
          inc         di
          mov         byte ptr es:[di],114 ;r
          inc         di
          mov         byte ptr es:[di],108 ;l
          inc         di
          mov         byte ptr es:[di],100 ;d
          inc         di
;
; pass string back to revelation
;
          xor         al,al              ;non-dimensioned local variable
          xor         dx,dx              ;0 = number of the variable
          pop         di                 ;starting address
          mov         ah,10h             ;function to copy string to rev
          call        function
          ret
main      endp
cseg      ends
          end
* R/BASIC routine to illustrate a call to an assembly language routine
*
* this program calls an assembly language subroutine that
* gets the date and day of the week (0 thru 6)
*----------------------------------------------
DECLARE SUBROUTINE ASM.DATE,MSG
*----------------------------------------------
* call the assembly language routine passing 4 variables
ASM.DATE(DD,MM,YY,DAY)

* determine the day of the week
BEGIN CASE
  CASE DAY=0 ; DAY.OF.WEEK = 'Sunday'
  CASE DAY=1 ; DAY.OF.WEEK = 'Monday'
  CASE DAY=2 ; DAY.OF.WEEK = 'Tuesday'
  CASE DAY=3 ; DAY.OF.WEEK = 'Wednesday'
  CASE DAY=4 ; DAY.OF.WEEK = 'Thursday'
  CASE DAY=5 ; DAY.OF.WEEK = 'Friday'
  CASE DAY=6 ; DAY.OF.WEEK = 'Saturday'
  CASE 1 ; DAY.OF.WEEK = ''
END CASE

* display the results
SENTENCE = 'Results from Assembly Language Program:|'
MSG(SENTENCE:DAY.OF.WEEK:' ':MM:'/':DD:'/':YY,'','','')
STOP
;***************************************************************************
*
; Program ASM.DATE
;
; Written to be called from an R/BASIC program
; Will return the system date
; Affects the ax,cx,dx registers
;
; Calling parameters are:
;
; CALL ASM.DATE(DD, MM, YY, WEEKDAY)
;
; with ASM.DATE being this cataloged routine.
;
;***************************************************************************
*
cseg        segment          para public 'CODE'
            assume           cs:cseg
main        proc             far
            org              0             ; start at address zero
            db               'ASSM'        ; 4-byte flag
            db               2             ; identify as assembler routine
no_args     db               0             ; number of arguments passed
no_coms     dw               0             ; number of common variables
            dw               0             ; unused
function    dd               0             ; address for rev function calls
;***************************************************************************
;
; interrupt to get date
; returns: cx=year,dh=month,dl=day,al=day of week
;
            mov              ah,2ah       ;loaded for DOS interupt
            int              21h          ;DOS interupt
            push             dx           ;save for later
            push             ax           ;save for later
;
;           pass             yy
;
            mov              ah,12h       ;to pass integer back
            mov              al,00h       ;local non-dimensioned variable
            mov              dx,3         ;third parameter
            call             function     ;REV function
;
;           pass             weekday
;
            pop              cx           ;was in ax from DOS interupt
            xor              ch,ch        ;make sure ch is clear
            mov              ah,12h
            mov              al,00h
            mov              dx,4         ;fourth parameter
            call             function
;
;           pass             dd
;
            pop              cx           ;was in dx from DOS interupt
            push             cx           ;save for later
            xor              ch,ch        ;make sure ch is clear
            mov              ah,12h
            mov              al,00h
            mov              dx,1         ;first parameter
            call             function
;
;           pass             mm
;
            pop              cx           ;was in dx from DOS interupt
            mov              cl,ch        ;move ch to cl
            xor              ch,ch        ;clear out ch
            mov              ah,12h
            mov              al,00h
            mov              dx,2         ;second parameter
            call             function
            ret
main        endp
cseg        ends
            end
  • tips/revmedia/r11.txt
  • Last modified: 2024/06/19 20:20
  • by 127.0.0.1