Mail Archives: djgpp/1997/01/23/04:31:35
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 -