From: "gord armstrong" <gord.armstrong@canrem.com>
Newsgroups: comp.os.msdos.programmer
Subject: ass'y gurus
Date: 2 Sep 92 00:18:27 EST
Reply-To: "gord armstrong" <gord.armstrong@canrem.com>
Distribution: comp
Organization: Canada Remote Systems


Segments ARRRG!

'C' Compiler: Microsoft C 6.0, Assembler: TASM 2.0

I'm linking a 'C' and assembler prog together in DOS, and I need
to pass a pointer from a C prog to an assembler proc. For a SMALL
model this is not much of a problem since code and data are in the
same segment, as follows:

  char *ptr; // will use in other modules, make it global

main()
{
  ptr=malloc((unsigned int)1024); *ptr=0x55;
  get_value();  // call ass'y routine
  free(ptr);
}


DOSSEG
.MODEL SMALL
                public  _get_value:proc
.DATA
                extrn   _ptr:word
other_var       db  ?
.CODE
;--------------------------------------------------------
; _get_value
;--------------------------------------------------------
_get_value      proc
                procin              ;save stuff for 'C'
                mov     bx,word ptr _ptr
                mov     al,[bx]
                xor     ah,ah
                call    to_integer  ;get '55' as set in main()
                procout             ;restore stuff for 'C'
                ret
_get_value      endp

For a LARGE model, I can't seem to find a way or a keyword to
do it neatly. A 'malloc' in the large model has 'ptr' pointing
to another segment. I can make it work doing the following:

  char far *_ptr;
  unsigned int ptr_seg,ptr_off;

main()
{
  ptr=malloc((unsigned int)1024); *ptr=0x55;

  ptr_seg=FP_SEG(ptr); ptr_off=FP_OFF(ptr);

  get_value();  // call ass'y routine
  free(ptr);
}

DOSSEG
.MODEL LARGE
                public  _get_value:proc
.FARDATA
                extrn   _ptr_seg:word
                extrn   _ptr_off:word
.DATA
other_var       db  ?
.CODE
;--------------------------------------------------------
; _get_value
;--------------------------------------------------------
_get_value      proc
                procin                ;save stuff for 'C'
                assume  ds:@FARDATA   ;FAR for large model
                mov     ax,@FARDATA
                mov     ds,ax         ;...is now our DS
                mov     es,_ptr_seg
                mov     bx,_ptr_off

                assume  ds:@DATA      ;put back DS for 'other_var'
                mov     ax,@DATA
                mov     ds,ax

                mov     al,es:[bx]    ;get '55' as set in main()
                xor     ah,ah
                call    to_integer
                procout             ;restore stuff for 'C'
                ret
_get_value      endp

It works, but it looks messy, is there a neater way of doing this?
If I use OS/2, I won't have this problem since it uses protected
mode...right?

All help appreciated!
---------------------------------------------------------------------
gord.armstrong@canremote.com   "If you blow chunks and she comes
                                back, she's yours. If you spew and
                                she bolts, it was never meant to be"
                                - Wayne's World
--
Canada Remote Systems  - Toronto, Ontario/Detroit, MI
World's Largest PCBOARD System - 416-629-7000/629-7044