;I have a solution.

But, I am slightly embaressed -- any ASM ;guru will tell you the PUSH BP is in the wrong place for setting ;up a regular frame, and so the code is slightly more complicated ;than it otherwise needs to be. This is true, but I was writing these ;originally in 1981 for PC-DOS 1.0 then 1.1, on a PC w/192k and ;two SINGLE side floppy disk drives. The IBM Fortran v 1.0 ;and IBM MASM v 1.0 (MS relabels, of course) documented ;interfacing the two in VERY sketchy terms. Also when most of ;this code was written, although experienced at 360 BAL, I was an ;x86 asm novice. ; ;By the time, some years later, that I realized the frame setup ;was back-assward - this code was in the "it ain't broke, don't ;fix it" mode. ; ;The macros & structs allow ASM routines to interface to ;(known to be working from my own personal testing) ;IBM Fortran v 1.0 & 2.0, MS Fortran 3.2, 3.3, 3.31, 4.0, 4.1, 5.0 ;and 5.1 -- I expect MS Fortran 3.1 will prove no problem. ;These can also be used to interface to IBM Pascal v 1.0 & 2.0, ;MS Pascal 3.31, QuickBasic 4.5 and MS C 5.1, 6.0 C/C++ 7 ;and VC 1.xx. ; ;Note that MS HLL's use a very strange set of methods to retrieve ;real values on return -- hide the real in an integer and ;use EQUIVALENCE to access it as a real at least until ;you start feeling really comfortable with ASM /HLL interfacing. ; ;Final note -- the files attached (and include file for asm and an ;example asm source using it) are Copyright -- As the author ;I hereby grant permission for USE and DISTRIBUTION ;per the Gnu Public License Version 2. ;-;Kevin G. Rhoads ;---------------------------------------------------------FORFRAME.INC: ;

; Copyright (c) 1997, 1981-1994 Kevin G. Rhoads - all rights reserved. ; ; Permission for use and distribution in accordance with the ; Gnu Public License is granted. You do not have permission ; to copy this material if you do not accept the terms of the ; Gnu Public License. PROVIDED AS IS. ; ; FORTRAN stack frame structures for MASM, originally written for ; IBM FORTRAN v1.0 & IBM MASM v1.0 - (c) Kevin G. Rhoads, 1981 & 1982. ; save/restore macros, code header & near/far returns added, and frame ; structures extended 1986 for MicroSoft FORTRAN v3.2 & v3.3 - (c) 1986 ; Kevin G. Rhoads. Note that these stack frame structures have been ; tested with IBM FORTRAN v1.0, v2.0; MicroSoft FORTRAN v3.2, 3.3, 3.31, 4.1 & 5.1 ; They are also suited for interface to IBM Pascal v1.0 & 2.0; MicroSoft Pascal ; v3.3 & 3.31 provided arguments are passed by reference (i.e., VARS) or are ; addresses passed by value -- FORTRAN expects pass by reference & large model ; (segment:offset) addresses ; These definitions are also suitable for QuickBasic 4.5, MS C 5.1, 6.0, C/C++ 7 ; VC 1.0, 1.5 with appropriate definitions on the calling side. ; ; The first set of FRAME definitions are suitable for returning BYTEs/CHARs/INTs/LONGs ; For returning REALs/FLOATs &c see SFRAME definitions in latter half of file. ; ;------------------------------------------------------------------------; RETURN OF FLOATS OR NON-TRIVIAL STRUCTS IS OFTEN STRANGE -- see SFRAME ; definitions after FRAME definitions. ;------------------------------------------------------------------------; ; Originally designed for FAR, 16bit calling (all stack based). ; These should also work for NEAR, 32bit, STACK based calling with minor mods ; [ see FRAME32.MAC ] ; .xlist ; ; TYPE 1 - simple return value ; frame struc for no arg subroutine

; ; ; ; ; bit) address ; frame0 saveflags0 savedi0 savesi0 saveds0 savebp0 saveret0 frame0 ; ; ; ; ; ; ; ; ; bit) address ; frame1 saveflags1 savedi1 savesi1 saveds1 savebp1 saveret1 argone1 frame1 offone1

FORTRAN/Pascal external procedure calling convention simple return value (1, 2 or 4 bytes - char, int, long or pointer) one byte return in AL character*1, logical*1 integer*1 or [C] char two byte return in AX integer*2, logical*2 or [C] short, address offset four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 struc dw dw dw dw dw dd ends ;frame for stack access ;save area for caller's ;save area for caller's ;save area for caller's ;save area for caller's ;save area for caller's ;return address for far

? ? ? ? ? ?

flags di si ds bp return

frame structure for 1 arg subroutine FORTRAN/Pascal external subroutine calling convention segment:[offset] address provided on stack for arg FORTRAN external procedure calling convention simple return value (1, 2 or 4 bytes - char, int, long or pointer) one byte return in AL character*1, logical*1 integer*1 or [C] char two byte return in AX integer*2, logical*2 or [C] short, address offset four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 struc dw dw dw dw dw dd dd ends equ ;frame for stack access - 1 arg ;save area for caller's flags ;save area for caller's di ;save area for caller's si ;save area for caller's ds ;save area for caller's bp ;return address for far return ;first arg - only arg: address

? ? ? ? ? ? ? argone1

segone1 ; ; ; ; ; ; ; ; ; bit) address ; frame2 saveflags2 savedi2 savesi2 saveds2 savebp2 saveret2 argtwo2 argone2 frame2 offtwo2 segtwo2 offone2 segone2 ; ; ; ; ; ; ; ; ; bit) address

equ

argone1 + 2

frame declaration for two arg subroutine FORTRAN/Pascal calling conventions for external procedure segment:[offset] address provided on stack for arg FORTRAN external procedure calling convention simple return value (1, 2 or 4 bytes - char, int, long or pointer) one byte return in AL character*1, logical*1 integer*1 or [C] char two byte return in AX integer*2, logical*2 or [C] short, address offset four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 struc dw dw dw dw dw dd dd dd ends equ equ equ equ ;frame structure for stack - two args ;save area for caller's flags ;save area for caller's di ;save area for caller's si ;save area for caller's ds ;save area for caller's bp ;return address for far return ;address of second operand ;first operand's address

? ? ? ? ? ? ? ?

argtwo2 argtwo2 + 2 argone2 argone2 + 2

frame struc for three arg subroutine FORTRAN/Pascal external procedure call convention segment:[offset] address provided on stack for arg FORTRAN external procedure calling convention simple return value (1, 2 or 4 bytes - char, int, long or pointer) one byte return in AL character*1, logical*1 integer*1 or [C] char two byte return in AX integer*2, logical*2 or [C] short, address offset four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16

; frame3 struc ;three arg struc for accessing stack saveflags3 dw ? ;save area for caller's flags savedi3 dw ? ;save area for caller's di savesi3 dw ? ;save area for caller's si saveds3 dw ? ;save area for caller's ds savebp3 dw ? ;save area for caller's bp saveret3 dd ? ;return address for far return argthree3 dd ? ;address of third operand argtwo3 dd ? ;address of second operand argone3 dd ? ;first operand's address frame3 ends offthree3 equ argthree3 segthree3 equ argthree3 + 2 offtwo3 equ argtwo3 segtwo3 equ argtwo3 + 2 offone3 equ argone3 segone3 equ argone3 + 2 ; ; ; frame struc for four arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; simple return value (1, 2 or 4 bytes - char, int, long or pointer) ; one byte return in AL character*1, logical*1 integer*1 or [C] char ; two byte return in AX integer*2, logical*2 or [C] short, address offset ; four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 bit) address ; frame4 struc ;four arg struc for accessing stack saveflags4 dw ? ;save area for caller's flags savedi4 dw ? ;save area for caller's di savesi4 dw ? ;save area for caller's si saveds4 dw ? ;save area for caller's ds savebp4 dw ? ;save area for caller's bp saveret4 dd ? ;return address for far return

argfour4 dd ? ;address of fourth operand argthree4 dd ? ;address of third operand argtwo4 dd ? ;address of second operand argone4 dd ? ;first operand's address frame4 ends offfour4 equ argfour4 segfour4 equ argfour4 + 2 offthree4 equ argthree4 segthree4 equ argthree4 + 2 offtwo4 equ argtwo4 segtwo4 equ argtwo4 + 2 offone4 equ argone4 segone4 equ argone4 + 2 ; ; frame struc for five arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; simple return value (1, 2 or 4 bytes - char, int, long or pointer) ; one byte return in AL character*1, logical*1 integer*1 or [C] char ; two byte return in AX integer*2, logical*2 or [C] short, address offset ; four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 bit) address ; frame5 struc ;five arg struc for accessing stack saveflags5 dw ? ;save area for caller's flags savedi5 dw ? ;save area for caller's di savesi5 dw ? ;save area for caller's si saveds5 dw ? ;save area for caller's ds savebp5 dw ? ;save area for caller's bp saveret5 dd ? ;return address for far return argfive5 dd ? ;address of fifth operand argfour5 dd ? ;address of fourth operand argthree5 dd ? ;address of third operand argtwo5 dd ? ;address of second operand argone5 dd ? ;first operand's address frame5 ends

offfive5 equ argfive5 segfive5 equ argfive5 + 2 offfour5 equ argfour5 segfour5 equ argfour5 + 2 offthree5 equ argthree5 segthree5 equ argthree5 + 2 offtwo5 equ argtwo5 segtwo5 equ argtwo5 + 2 offone5 equ argone5 segone5 equ argone5 + 2 ; ; frame struc for six arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; simple return value (1, 2 or 4 bytes - char, int, long or pointer) ; one byte return in AL character*1, logical*1 integer*1 or [C] char ; two byte return in AX integer*2, logical*2 or [C] short, address offset ; four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 bit) address ; frame6 struc ;six arg struc for accessing stack saveflags6 dw ? ;save area for caller's flags savedi6 dw ? ;save area for caller's di savesi6 dw ? ;save area for caller's si saveds6 dw ? ;save area for caller's ds savebp6 dw ? ;save area for caller's bp saveret6 dd ? ;return address for far return argsix6 dd ? ;address of sixth operand argfive6 dd ? ;address of fifth operand argfour6 dd ? ;address of fourth operand argthree6 dd ? ;address of third operand argtwo6 dd ? ;address of second operand argone6 dd ? ;first operand's address frame6 ends offsix6 equ argsix6 segsix6 equ argsix6 + 2

offfive6 equ argfive6 segfive6 equ argfive6 + 2 offfour6 equ argfour6 segfour6 equ argfour6 + 2 offthree6 equ argthree6 segthree6 equ argthree6 + 2 offtwo6 equ argtwo6 segtwo6 equ argtwo6 + 2 offone6 equ argone6 segone6 equ argone6 + 2 ; ; frame struc for seven arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; simple return value (1, 2 or 4 bytes - char, int, long or pointer) ; one byte return in AL character*1, logical*1 integer*1 or [C] char ; two byte return in AX integer*2, logical*2 or [C] short, address offset ; four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 bit) address ; frame7 struc ;seven arg struc for accessing stack saveflags7 dw ? ;save area for caller's flags savedi7 dw ? ;save area for caller's di savesi7 dw ? ;save area for caller's si saveds7 dw ? ;save area for caller's ds savebp7 dw ? ;save area for caller's bp saveret7 dd ? ;return address for far return argseven7 dd ? ;address of seventh operand argsix7 dd ? ;address of sixth operand argfive7 dd ? ;address of fifth operand argfour7 dd ? ;address of fourth operand argthree7 dd ? ;address of third operand argtwo7 dd ? ;address of second operand argone7 dd ? ;first operand's address frame7 ends offseven7 equ argseven7

segseven7 equ argseven7 + 2 offsix7 equ argsix7 segsix7 equ argsix7 + 2 offfive7 equ argfive7 segfive7 equ argfive7 + 2 offfour7 equ argfour7 segfour7 equ argfour7 + 2 offthree7 equ argthree7 segthree7 equ argthree7 + 2 offtwo7 equ argtwo7 segtwo7 equ argtwo7 + 2 offone7 equ argone7 segone7 equ argone7 + 2 ; ; frame struc for eight arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; simple return value (1, 2 or 4 bytes - char, int, long or pointer) ; one byte return in AL character*1, logical*1 integer*1 or [C] char ; two byte return in AX integer*2, logical*2 or [C] short, address offset ; four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 bit) address ; frame8 struc ;eight arg struc for accessing stack saveflags8 dw ? ;save area for caller's flags savedi8 dw ? ;save area for caller's di savesi8 dw ? ;save area for caller's si saveds8 dw ? ;save area for caller's ds savebp8 dw ? ;save area for caller's bp saveret8 dd ? ;return address for far return argeight8 dd ? ;address of eighth operand argseven8 dd ? ;address of seventh operand argsix8 dd ? ;address of sixth operand argfive8 dd ? ;address of fifth operand argfour8 dd ? ;address of fourth operand argthree8 dd ? ;address of third operand

argtwo8 dd ? ;address of second operand argone8 dd ? ;first operand's address frame8 ends offeight8 equ argeight8 segeight8 equ argeight8 + 2 offseven8 equ argseven8 segseven8 equ argseven8 + 2 offsix8 equ argsix8 segsix8 equ argsix8 + 2 offfive8 equ argfive8 segfive8 equ argfive8 + 2 offfour8 equ argfour8 segfour8 equ argfour8 + 2 offthree8 equ argthree8 segthree8 equ argthree8 + 2 offtwo8 equ argtwo8 segtwo8 equ argtwo8 + 2 offone8 equ argone8 segone8 equ argone8 + 2 ; ; frame struc for nine arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; simple return value (1, 2 or 4 bytes - char, int, long or pointer) ; one byte return in AL character*1, logical*1 integer*1 or [C] char ; two byte return in AX integer*2, logical*2 or [C] short, address offset ; four byte return in DX:AX integer*4, logical*4 or [C] long, segmented (16 bit) address ; frame9 struc ;nine arg struc for accessing stack saveflags9 dw ? ;save area for caller's flags savedi9 dw ? ;save area for caller's di savesi9 dw ? ;save area for caller's si saveds9 dw ? ;save area for caller's ds savebp9 dw ? ;save area for caller's bp saveret9 dd ? ;return address for far return

argnine9 dd ? ;address of ninth operand argeight9 dd ? ;address of eighth operand argseven9 dd ? ;address of seventh operand argsix9 dd ? ;address of sixth operand argfive9 dd ? ;address of fifth operand argfour9 dd ? ;address of fourth operand argthree9 dd ? ;address of third operand argtwo9 dd ? ;address of second operand argone9 dd ? ;first operand's address frame9 ends offnine9 equ argnine9 segnine9 equ argnine9 + 2 offeight9 equ argeight9 segeight9 equ argeight9 + 2 offseven9 equ argseven9 segseven9 equ argseven9 + 2 offsix9 equ argsix9 segsix9 equ argsix9 + 2 offfive9 equ argfive9 segfive9 equ argfive9 + 2 offfour9 equ argfour9 segfour9 equ argfour9 + 2 offthree9 equ argthree9 segthree9 equ argthree9 + 2 offtwo9 equ argtwo9 segtwo9 equ argtwo9 + 2 offone9 equ argone9 segone9 equ argone9 + 2 ; ; ; TYPE 2 - float or non-trivial return value ; ;!on return the retval offset must be in AX and the restored DS value in DX ! ; ; MS FORTRAN/MS Pascal return convention for REAL*4 REAL*8 and with MS C for ; STRUCTs, RECORDS &c (MS C floats and doubles are returned in global __fac

; but then SEG:OFF of __fac must be in DX:AX as here) ; ; CALLER allocates storage for return value in DGROUP segment(s) (DS on entry) ; and pushes offset before pushing addresses of args (all frames here based on ; large model, pass by reference (FORTRAN default, Pascal with VARS)) ; to return value copy to return value location AND RETURN WITH SEGMENT:OFFSET ; OF RETURN VALUE LOCATION IN DX:AX !!!!! (w/o this last caller goes to flooby ; space and gets garbage) ; ; IBM FORTRAN v1 and v2, IBM Pascal v1 and v2 use essentially same conventions ; ; Borland C uses something like this for 3 byte and 5 or larger byte structs ; Borland C returns all 1 byte values in AL, 2 bytes in AX, and 4 bytes in DX:AX ; except floats; floats, doubles and long doubles are returned on 8087 ST(0) stack top ; ; ; frame struc for no arg subroutine ; FORTRAN/Pascal external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; before CALLing routine ; sframe0 struc ;frame for stack access savedflags0 dw ? ;save area for caller's flags saveddi0 dw ? ;save area for caller's di savedsi0 dw ? ;save area for caller's si savedds0 dw ? ;save area for caller's ds savedbp0 dw ? ;save area for caller's bp savedret0 dd ? ;return address for far return retvaloffs0 dw ? ;offsset (re DS) of storage for return value sframe0 ends ; ; frame structure for 1 arg subroutine ; FORTRAN/Pascal external subroutine calling convention ; segment:[offsset] address provided on stack for arg ; FORTRAN external procedure calling convention

; ; ; ; sframe1 savedflags1 saveddi1 savedsi1 savedds1 savedbp1 savedret1 retvaloffs1 argsone1 sframe1 offsone1 segsone1 ; ; ; ; ; ; ; ; ; sframe2 savedflags2 saveddi2 savedsi2 savedds2 savedbp2 savedret2 retvaloffs2 argstwo2 argsone2 sframe2

complex return value (struct, record, float or double) caller has allocated space for retval in DS and pushed offset after last arg and before CALLing routine struc dw dw dw dw dw dd dw dd ends equ equ ? ? ? ? ? ? ? ? ;frame for stack access - 1 arg ;save area for caller's flags ;save area for caller's di ;save area for caller's si ;save area for caller's ds ;save area for caller's bp ;return address for far return ;offset (re DS) of storage for return value ;first arg - only arg: address

argsone1 argsone1 + 2

frame declaration for two arg subroutine FORTRAN/Pascal calling conventions for external procedure segment:[offset] address provided on stack for arg FORTRAN external procedure calling convention complex return value (struct, record, float or double) caller has allocated space for retval in DS and pushed offset after last arg and before CALLing routine struc dw dw dw dw dw dd dw dd dd ends ? ? ? ? ? ? ? ? ? ;frame structure for stack - two args ;save area for caller's flags ;save area for caller's di ;save area for caller's si ;save area for caller's ds ;save area for caller's bp ;return address for far return ;offset (re DS) of storage for return value ;address of second operand ;first operand's address

offstwo2 equ argstwo2 segstwo2 equ argstwo2 + 2 offsone2 equ argsone2 segsone2 equ argsone2 + 2 ; ; frame struc for three arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] address provided on stack for arg ; FORTRAN external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; after last arg and before CALLing routine ; sframe3 struc ;three arg struc for accessing stack savedflags3 dw ? ;save area for caller's flags saveddi3 dw ? ;save area for caller's di savedsi3 dw ? ;save area for caller's si savedds3 dw ? ;save area for caller's ds savedbp3 dw ? ;save area for caller's bp savedret3 dd ? ;return address for far return retvaloffs3 dw ? ;offset (re DS) of storage for return value argsthree3 dd ? ;address of third operand argstwo3 dd ? ;address of second operand argsone3 dd ? ;first operand's address sframe3 ends offsthree3 equ argsthree3 segsthree3 equ argsthree3 + 2 offstwo3 equ argstwo3 segstwo3 equ argstwo3 + 2 offsone3 equ argsone3 segsone3 equ argsone3 + 2 ; ; ; frame struc for four arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args

; FORTRAN external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; after last arg and before CALLing routine ; sframe4 struc ;four arg struc for accessing stack savedflags4 dw ? ;save area for caller's flags saveddi4 dw ? ;save area for caller's di savedsi4 dw ? ;save area for caller's si savedds4 dw ? ;save area for caller's ds savedbp4 dw ? ;save area for caller's bp savedret4 dd ? ;return address for far return retvaloffs4 dw ? ;offset (re DS) of storage for return value argsfour4 dd ? ;address of fourth operand argsthree4 dd ? ;address of third operand argstwo4 dd ? ;address of second operand argsone4 dd ? ;first operand's address sframe4 ends offsfour4 equ argsfour4 segsfour4 equ argsfour4 + 2 offsthree4 equ argsthree4 segsthree4 equ argsthree4 + 2 offstwo4 equ argstwo4 segstwo4 equ argstwo4 + 2 offsone4 equ argsone4 segsone4 equ argsone4 + 2 ; ; frame struc for five arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; after last arg and before CALLing routine ; sframe5 struc ;five arg struc for accessing stack

savedflags5 dw ? ;save area for caller's flags saveddi5 dw ? ;save area for caller's di savedsi5 dw ? ;save area for caller's si savedds5 dw ? ;save area for caller's ds savedbp5 dw ? ;save area for caller's bp savedret5 dd ? ;return address for far return retvaloffs5 dw ? ;offset (re DS) of storage for return value argsfive5 dd ? ;address of fifth operand argsfour5 dd ? ;address of fourth operand argsthree5 dd ? ;address of third operand argstwo5 dd ? ;address of second operand argsone5 dd ? ;first operand's address sframe5 ends offsfive5 equ argsfive5 segsfive5 equ argsfive5 + 2 offsfour5 equ argsfour5 segsfour5 equ argsfour5 + 2 offsthree5 equ argsthree5 segsthree5 equ argsthree5 + 2 offstwo5 equ argstwo5 segstwo5 equ argstwo5 + 2 offsone5 equ argsone5 segsone5 equ argsone5 + 2 ; ; frame struc for six arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; after last arg and before CALLing routine ; sframe6 struc ;six arg struc for accessing stack savedflags6 dw ? ;save area for caller's flags saveddi6 dw ? ;save area for caller's di savedsi6 dw ? ;save area for caller's si

savedds6 dw ? ;save area for caller's ds savedbp6 dw ? ;save area for caller's bp savedret6 dd ? ;return address for far return retvaloffs6 dw ? ;offset (re DS) of storage for return value argssix6 dd ? ;address of sixth operand argsfive6 dd ? ;address of fifth operand argsfour6 dd ? ;address of fourth operand argsthree6 dd ? ;address of third operand argstwo6 dd ? ;address of second operand argsone6 dd ? ;first operand's address sframe6 ends offssix6 equ argssix6 segssix6 equ argssix6 + 2 offsfive6 equ argsfive6 segsfive6 equ argsfive6 + 2 offsfour6 equ argsfour6 segsfour6 equ argsfour6 + 2 offsthree6 equ argsthree6 segsthree6 equ argsthree6 + 2 offstwo6 equ argstwo6 segstwo6 equ argstwo6 + 2 offsone6 equ argsone6 segsone6 equ argsone6 + 2 ; ; frame struc for seven arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; after last arg and before CALLing routine ; sframe7 struc ;seven arg struc for accessing stack savedflags7 dw ? ;save area for caller's flags saveddi7 dw ? ;save area for caller's di savedsi7 dw ? ;save area for caller's si

savedds7 dw ? ;save area for caller's ds savedbp7 dw ? ;save area for caller's bp savedret7 dd ? ;return address for far return retvaloffs7 dw ? ;offset (re DS) of storage for return value argsseven7 dd ? ;address of seventh operand argssix7 dd ? ;address of sixth operand argsfive7 dd ? ;address of fifth operand argsfour7 dd ? ;address of fourth operand argsthree7 dd ? ;address of third operand argstwo7 dd ? ;address of second operand argsone7 dd ? ;first operand's address sframe7 ends offsseven7 equ argsseven7 segsseven7 equ argsseven7 + 2 offssix7 equ argssix7 segssix7 equ argssix7 + 2 offsfive7 equ argsfive7 segsfive7 equ argsfive7 + 2 offsfour7 equ argsfour7 segsfour7 equ argsfour7 + 2 offsthree7 equ argsthree7 segsthree7 equ argsthree7 + 2 offstwo7 equ argstwo7 segstwo7 equ argstwo7 + 2 offsone7 equ argsone7 segsone7 equ argsone7 + 2 ; ; frame struc for eight arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args ; FORTRAN external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; after last arg and before CALLing routine ; sframe8 struc ;eight arg struc for accessing stack

savedflags8 dw ? ;save area for caller's flags saveddi8 dw ? ;save area for caller's di savedsi8 dw ? ;save area for caller's si savedds8 dw ? ;save area for caller's ds savedbp8 dw ? ;save area for caller's bp savedret8 dd ? ;return address for far return retvaloffs8 dw ? ;offset (re DS) of storage for return value argseight8 dd ? ;address of eighth operand argsseven8 dd ? ;address of seventh operand argssix8 dd ? ;address of sixth operand argsfive8 dd ? ;address of fifth operand argsfour8 dd ? ;address of fourth operand argsthree8 dd ? ;address of third operand argstwo8 dd ? ;address of second operand argsone8 dd ? ;first operand's address sframe8 ends offseight8 equ argseight8 segseight8 equ argseight8 + 2 offsseven8 equ argsseven8 segsseven8 equ argsseven8 + 2 offssix8 equ argssix8 segssix8 equ argssix8 + 2 offsfive8 equ argsfive8 segsfive8 equ argsfive8 + 2 offsfour8 equ argsfour8 segsfour8 equ argsfour8 + 2 offsthree8 equ argsthree8 segsthree8 equ argsthree8 + 2 offstwo8 equ argstwo8 segstwo8 equ argstwo8 + 2 offsone8 equ argsone8 segsone8 equ argsone8 + 2 ; ; frame struc for nine arg subroutine ; FORTRAN/Pascal external procedure call convention ; segment:[offset] addresses provided on stack for args

; FORTRAN external procedure calling convention ; complex return value (struct, record, float or double) ; caller has allocated space for retval in DS and pushed offset ; after last arg and before CALLing routine ; sframe9 struc ;nine arg struc for accessing stack savedflags9 dw ? ;save area for caller's flags saveddi9 dw ? ;save area for caller's di savedsi9 dw ? ;save area for caller's si savedds9 dw ? ;save area for caller's ds savedbp9 dw ? ;save area for caller's bp savedret9 dd ? ;return address for far return retvaloffs9 dw ? ;offset (re DS) of storage for return value argsnine9 dd ? ;address of ninth operand argseight9 dd ? ;address of eighth operand argsseven9 dd ? ;address of seventh operand argssix9 dd ? ;address of sixth operand argsfive9 dd ? ;address of fifth operand argsfour9 dd ? ;address of fourth operand argsthree9 dd ? ;address of third operand argstwo9 dd ? ;address of second operand argsone9 dd ? ;first operand's address sframe9 ends offsnine9 equ argsnine9 segsnine9 equ argsnine9 + 2 offseight9 equ argseight9 segseight9 equ argseight9 + 2 offsseven9 equ argsseven9 segsseven9 equ argsseven9 + 2 offssix9 equ argssix9 segssix9 equ argssix9 + 2 offsfive9 equ argsfive9 segsfive9 equ argsfive9 + 2 offsfour9 equ argsfour9 segsfour9 equ argsfour9 + 2 offsthree9 equ argsthree9

segsthree9 equ argsthree9 + 2 offstwo9 equ argstwo9 segstwo9 equ argstwo9 + 2 offsone9 equ argsone9 segsone9 equ argsone9 + 2 ; ; ; NB - if modifications are made to the save/restore macros the frame ; definitions above must be modified to match save macro push bp ;IBM FORTRAN v1.0,2.0 IBM Pascal v1.0,2.0 & MicroSoft push ds ;versions 3.x, 4.x, 5.x require preservation of BP & DS push si ;Some versions of MS C require preservation of SI, DI push di pushf ;some versions of MS C, FORTRAN require preservation of mov bp,sp ;establishes stack frame pointing to saved flags cld ; direction flag endm restore macro ; mov sp,bp ;restore stack frame from local storage allocation ; ;this is commented out because it is unnecessary ; ;no local storage is allocated popf ;some versions of MS C, FORTRAN require preservation of pop di ; direction flag, some require preservation of SI, DI pop si ; almost all require preservation of DS pop ds ;IBM FORTRAN v1.0,2.0 IBM Pascal v1.0,2.0 & MicroSoft pop bp ;versions 3.x, 4.x, 5.x require preservation of BP & DS endm ksave macro push bp ;IBM FORTRAN v1.0,2.0 IBM Pascal v1.0,2.0 & MicroSoft push ds ;versions 3.x, 4.x, 5.x require preservation of BP & DS push si ;Some versions of MS C require preservation of SI, DI push di pushf ;some versions of MS C, FORTRAN require preservation of mov bp,sp ;establishes stack frame pointing to saved flags cld ; direction flag

endm krestore macro ; mov sp,bp ;restore stack frame from local storage allocation ; ;this is commented out because it is unnecessary ; ;no local storage is allocated popf ;some versions of MS C, FORTRAN require preservation of pop di ; direction flag, some require preservation of SI, DI pop si ; almost all require preservation of DS pop ds ;IBM FORTRAN v1.0,2.0 IBM Pascal v1.0,2.0 & MicroSoft pop bp ;versions 3.x, 4.x, 5.x require preservation of BP & DS endm save16 macro push bp ;IBM FORTRAN v1.0,2.0 IBM Pascal v1.0,2.0 & MicroSoft push ds ;versions 3.x, 4.x, 5.x require preservation of BP & DS push si ;Some versions of MS C require preservation of SI, DI push di pushf ;some versions of MS C, FORTRAN require preservation of mov bp,sp ;establishes stack frame pointing to saved flags cld ; direction flag endm restore16 macro ; mov sp,bp ;restore stack frame from local storage allocation ; ;this is commented out because it is unnecessary ; ;no local storage is allocated popf ;some versions of MS C, FORTRAN require preservation of pop di ; direction flag, some require preservation of SI, DI pop si ; almost all require preservation of DS pop ds ;IBM FORTRAN v1.0,2.0 IBM Pascal v1.0,2.0 & MicroSoft pop bp ;versions 3.x, 4.x, 5.x require preservation of BP & DS endm ; ; RET_FAR MACRO DB 0CBH ENDM ;

RET_FAR_POP DB DW ENDM ; RET_NEAR DB ENDM ; RET_NEAR_POP DB DW ENDM ; SRET MACRO IFB ELSE

MACRO 0CAH X MACRO 0C3H MACRO 0C2H X X <X> DB DB DW

X

X

0C3H 0C2H X

ENDIF ENDM ; NRET MACRO IFB ELSE DB DW ENDIF ENDM ; LRET MACRO IFB ELSE X <X> DB 0C2H X X <X> DB

0C3H

0CBH

DB DW ENDIF ENDM ; FRET MACRO IFB ELSE DB DW ENDIF ENDM X <X> DB

0CAH X

0CBH 0CAH X

; ; ; ;*******************header ****************************** ; ;code header macro defined here ; header macro ; ; DATA segment WORD PUBLIC 'DATA' USE16 DATA ends _DATA SEGMENT WORD PUBLIC 'DATA' USE16 _DATA ENDS CONST SEGMENT WORD PUBLIC 'CONST' USE16 SEG_FAC DW SEG __fac CONST ENDS _BSS SEGMENT WORD PUBLIC 'BSS' USE16 _BSS ENDS DGROUP EXTRN GROUP CONST, _BSS, _DATA, DATA

__fac:QWORD

;C7 OR LATER EXTRN __fltused:ABS ;C6 OR EARLIER ;EXTRN __fltused:NEAR ; code segment assume ; ; endm ; wswapeax macro xchg db xchg endm ; wswapebx macro xchg db xchg endm ; wswapecx macro xchg db xchg endm ; wswapedx macro xchg db xchg endm ;

WORD PUBLIC 'CODE' USE16 cs:code,ds:dgroup,es:NOTHING,ss:dgroup ;header al,ah 066h,00Fh,0C8h al,ah ;wswapeax bl,bh 066h,00Fh,0CBh bl,bh ;wswapebx cl,ch 066h,00Fh,0C9h cl,ch ;wswapecx dl,dh 066h,00Fh,0CAh dl,dh ;wswapedx

; bswap

eax

; bswap

ebx

; bswap

ecx

; bswap

edx

wswapesi

macro xchg xchg db xchg xchg endm macro xchg xchg db xchg xchg endm macro xchg xchg db xchg xchg endm

ax,si al,ah 066h,00Fh,0C8h al,ah ax,si ;wswapesi ax,di al,ah 066h,00Fh,0C8h al,ah ax,di ;wswapedi ax,bp al,ah 066h,00Fh,0C8h al,ah ax,bp ;wswapebp

; bswap

eax

; wswapedi

; bswap

eax

; wswapebp

; bswap

eax

; ; .list