delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/01/23/04:31:35

From: beppu AT rigel DOT oac DOT uci DOT edu (John Beppu)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Help with NASM
Date: 22 Jan 1997 22:02:40 GMT
Organization: University of California, Irvine
Lines: 221
Message-ID: <5c62q0$6o9@news.service.uci.edu>
References: <32E6660A DOT 387C AT vesatec DOT com>
NNTP-Posting-Host: rigel.oac.uci.edu
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

In article <32E6660A DOT 387C AT vesatec DOT com>,
Vicente A.S. Werner <mcleod AT vesatec DOT com> wrote:

>Hello all!
>
>I've been a total assembler programmer for years , without using c or
>other lenguages , now I've switched to DJGPP C system totally. But 
>I don't have any idea on how to interface rutines on c with assembly
>ones . I'm using NASM because its sintaxis is similar to the old 
>intel one . Any one can help me on how to export and import variables 
>and such?
>
>Thanks in Advance
>
>Vicent A.S. Werner aka [Mcleod]


Here's a little overview of things to keep in mind when writing
functions in straight assembly for use w/ DJGPP.

  [Registers]

  ebx,ebp,edi,esi	: these must be preserved
  eax			: return value goes here
  edx:eax		: return (64bit) integer
  ST0			: return float

  (note) : look at the assembly output of one of your C programs
  	 : (by doing gcc -S ...) to see how DJGPP returns things.


  [Parameter Passing]
   
  suppose one had a function defined like:

  void phunction
       (
       long* address
       long c
       )
  {
    // blah......
  }

  The stack will look like this while execution inside phunction 
  is in process.  (This applies to C--I don't know how C++ deals
  with parameters.  Maybe someone else could help.)

  [esp+08]	c
  [esp+04]	address
  [esp+00]	return address

  (note) : The parameter passing convention can be changed through
         : command line switches to make djgpp use registers to
         : pass in parameters.  The default, however, is to strictly
         : use the stack to pass parameters.  Again, look at the
         : assembly output of a C program to see how DJGPP wants
         : parameters to be dealt with.


  [NASM hints]

  I use CPP in conjunction with NASM to make my life a little easier.
  Here's an example of what I do.


#define b	byte
#define w	word
#define d	dword

/*  This will draw the region defined by the edge list "edge"
    in accordance to the distortion map "dist".  Drawing will
    be done in the buffer starting at (*adr0).
 
void    distortion_fill (
        long* adr0,     // address of buffer to fill to
        long* adr1,     // address of buffer to be distorted
        long* edge,     // ofs edge list
        long* dist      // ofs distortion map
        );
 
;; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°*/
 
#define frame   28
 
#define S0      esp+04  // limit(lineCounter)   (must not be 0)
#define S1      esp+08  // lineCounter          (aka n)
#define S2      esp+12  // distortion_index     (aka nn)
 
#define _ebx    esp+16
#define _edi    esp+20
#define _esi    esp+24
#define _ebp    esp+28
 
#define adr0    esp+frame+04
#define adr1    esp+frame+08
#define edge    esp+frame+12
#define dist    esp+frame+16
 
_distortion_fill:
 
        // enlarge stackframe
        // prepare edge & dist ptrs
 
                mov     ecx,[d esp]
                sub     esp,b frame
                mov     ebx,[d edge]
                mov     edx,[d dist]
                mov     [d esp],ecx     ; return address
 
        // save registers for djgpp
 
                nop
                mov     [_ebx],ebx
                mov     [_edi],edi
                nop
                mov     [_esi],esi
                mov     [_ebp],ebp
 
        // prepare variables for loop
 
                mov     edi,[d adr0]
 
                xor     ecx,ecx
                mov     esi,[d adr1]
                mov     eax,[d ebx]
                mov     d [S1],ecx      ; S1  = Ini(lineCounter)
                nop
                mov     edx,[d edx]     ; edx = dist[nn]
                mov     d [S0],eax      ; S0  = Lim(lineCounter)
                nop
                mov     ecx,[d ebx+4]   ; ecx = edge[n].elements
                mov     eax,[d ebx+8]   ; eax = edge[n].start
 
                mov     ebp,esi
                add     edx,eax
                add     esi,edx         ; esi
                mov     edx,[d dist]    ; edx = &distortion_map[0]
 
                xor     ecx,b -1
                add     edi,eax         ; edi
                inc     ecx             ; ecx
                add     ebp,eax         ; ebp
;ÚÄÄÄÄÄÄú
 
.lineFiller:
 
;  al = pixelHolder
; ebx = temp
; ecx = neg(limit(pixelCounter))
; edx = &distortion_map[nn]
; edi = adr0+edge[n].start              ; incremental progression
; esi = adr1+edge[n].start+dist[nn]     ; unpredictable
; ebp = adr1+edge[n].start
 
                mov     al,b [esi]
                mov     esi,ebp         ; esi = adr1+edge[n].start = ebp
                mov     ebx,[edx]
                add     edx,b 4
                add     esi,ebx         ; esi = (ebx = dist[nn]) + esi
                mov     b [edi],al
                inc     edi
                inc     ecx
                jnz     short .lineFiller
;ÀÄÄÄÄÄÄú
                // no more work?
 
                mov     eax,d [S1]
                mov     ebx,d [S0]
                inc     eax
                mov     d [S2],edx
                cmp     ebx,eax
                mov     ebx,d [edge]
                mov     d [S1],eax
                je      short .bye
 
                // prepare registers for another iteration
 
                mov     edx,d [S2]
                mov     eax,d [ebx+eax*8+4]
                mov     esi,d [adr1]
                add     esi,eax
                mov     ebx,d [edx]
                mov     edi,d [adr0]
                add     esi,ebx         ; esi
                add     edi,eax         ; edi
                mov     ebp,esi         ; ebp
                jmp     short .lineFiller
;ÀÄÄÄÄÄÄú
 
        // restore registers for djgpp
 
.bye:           mov     ebp,[_ebp]
                mov     esi,[_esi]
                mov     ebx,[_ebx]
                mov     edi,[_edi]
                retn    frame
 
#undef  frame
 
#undef  S0
#undef  S1
#undef  S2
 
#undef  _ebx
#undef  _edi
#undef  _esi
#undef  _ebp
 
#undef  adr0
#undef  adr1
#undef  edge
#undef  dist


  Read up on how CPP is invoked.  I think you'll find it to
  be helpful in dealing with NASM's lack of macro facilities.

 
-- 
  beppu AT uci DOT edu .............................................................

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019