delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2002/02/08/14:09:16

X-Authentication-Warning: delorie.com: mailnull set sender to djgpp-bounces using -f
From: Hans-Bernhard Broeker <broeker AT physik DOT rwth-aachen DOT de>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Uhm, nobody knows the answer or...
Date: 8 Feb 2002 17:48:31 GMT
Organization: Aachen University of Technology (RWTH)
Lines: 99
Message-ID: <a4131f$9bf$1@nets3.rz.RWTH-Aachen.DE>
References: <6e0d77f39bba940fee0e0149fb76a996 DOT 62691 AT mygate DOT mailgate DOT org> <a40i4b$oil$1 AT nets3 DOT rz DOT RWTH-Aachen DOT DE> <5563ab859c72dffdd2ded7c0f0edf714 DOT 62691 AT mygate DOT mailgate DOT org>
NNTP-Posting-Host: acp3bf.physik.rwth-aachen.de
X-Trace: nets3.rz.RWTH-Aachen.DE 1013190511 9583 137.226.32.75 (8 Feb 2002 17:48:31 GMT)
X-Complaints-To: abuse AT rwth-aachen DOT de
NNTP-Posting-Date: 8 Feb 2002 17:48:31 GMT
Originator: broeker@
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Well, OK, so I'll bite it...

Joel Saunders <jbs30000 AT aol DOT com> wrote:

> Ok, I have the variables:
> char *Screen_PTR = (char *)(0xB8000 + __djgpp_conventional_base);
> char My_Name[9] = {"J O E L "};
> I have the macro
> #define Mov_Byte(Src, Dest, Mov_Size)\

Hmm... it might be better to make that an inlined function ("extern
inline" in the header file).  Otherwise, you might end up in trouble
if someone passes somewhat more complicated arguments.

Of course, this particular example is completely moot --- just calling
memcpy() would produce the exact same result already. GCC has a
builtin inlined version of that standard function.

>         __asm__ __volatile__(\
>                 "cld\n\t"\
>                 "rep\n\t"\
>                 "movsb"\
>                 : :"S" (Src), "D" (Dest), "c" (Mov_Size))

If this were fully correct, you wouldn't need any __volatile__
qualifier.  That's usually only needed for insufficiently instrumented
extended asm blocks.

What you're saying is that you want Src in %esi, and Dest in %edi, and
Mov_Size into %ecx.  Fine.

> This works:
> Mov_Byte(&My_Name[0], &Screen_PTR[0], 8);
           ^^^^^^^^^^^
It shouldn't ever be necessary to write it this way.  Simply

	Mov_Byte(My_Name, Screen_PTR, 8);

should suffice.  Esp. if you used an inline function, so the compiler
gets a chance to know the types of the arguments to be passed to this
function, too.

> However, if I rewrite the macro like this:

Question: why do you want to rewrite it like this? Didn't the other
version work already?

> #define Mov_Byte(Src, Dest, Mov_Size)\
>         __asm__ __volatile__(\
>                 "cld\n\t"\
>                 "rep\n\t"\
>                 "movsb"\
>                 : :"S" (Src), "D" (Dest), "c" (Mov_Size)\
>                 :"%ecx", "%esi", "%edi"

That's wrong, indeed.  You're not supposed to have the same registers
in both the input/output and the clobber lists.  The clobber list is
for other registers modified by the code, but which are not in the
input/output lists.  There was a change in this area between GCC-2.8.1
and 2.95.something.  The error message has changed, but the solution
from the DJGPP FAQ (8.17) should still apply.  Unfortunately, that
particular GCC FAQ section it points no longer seems to be there.

In a nutshell: set up dummy variables (one per 'clobbered' register),
and set them up as output locacions for those registers.  As you're
going to mention some registers twice, this gets a bit more tricky:
you have to reference an earlier constraint by running index.
Furthermore, I don't think you have to mark esi and edi as clobbered,
for this: their values aren't actually modified by the code. Only ecx
is.

> Error: Can't find a register in class `CREG' while reloading `asm'.

The error message seems to have changed in recent GCC's, but I still
assume it's that same old problem.  IIRC, it used to say "fixed or
forbidden register was spilled".  

All that said, I think a correct version would look like this:

extern inline void Mov_Byte(void *Src, void *Dest, size_t Mov_Size)
{
	unsigned int dummy;
        __asm__ (
                "cld\n\t"
                "rep\n\t"
                "movsb"
                :"=c" (dummy)
	        :"S" (Src), "D" (Dest), "0" (Mov_Size)
	        :"memory"
	);
}

But note that this is 100% untested.



-- 
Hans-Bernhard Broeker (broeker AT physik DOT rwth-aachen DOT de)
Even if all the snow were burnt, ashes would remain.

- Raw text -


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