ftp.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/05/11/09:05:53

Xref: news2.mv.net comp.os.msdos.djgpp:3690
From: terra AT diku DOT dk (Morten Welinder)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Problems with inline asm of GCC 2.7.2
Date: 9 May 1996 12:03:01 GMT
Organization: Department of Computer Science, U of Copenhagen
Lines: 133
Sender: terra AT tyr DOT diku DOT dk
Message-ID: <4msmtl$f5h@vidar.diku.dk>
References: <9605081434 DOT aa25285 AT ailin DOT inti DOT edu DOT ar>
NNTP-Posting-Host: tyr.diku.dk
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

"Salvador Tropea,ICE" <salvador AT inti DOT edu DOT ar> writes:

>1) Problems with JCXZ.
>2) C Extensions to inline asm not supported under C++!!!???
>3) GCC is idiot or is a nest of bugs?
>4) Hey, ES,GS and FS are registers, but GCC don't know this.
>5) Conclutions.

>1) The following code works OK:

By chance, not by design.

>int countLines( void *buf, uint32 count )
>{
>register long Ret asm ("%eax");

>asm ("pushl %edx");
>asm ("pushl %ecx");
>asm ("pushl %edi");
>asm ("pushw %es");

>asm ("pushw %ds");
>asm ("popw  %es");

[snip]

>asm ("popl %edi");
>asm ("popl %ecx");
>asm ("popl %edx");
>return Ret;
>}


Put all this in _one_ asm statement or else there is no guarantee
that gcc won't use the cpu registers or the stack in between.


>  But if i replace the lines with // * for:

>asm ("Jcxz  countLines__2");

The "jcxz" instruction doesn't work as you think it does.  It is
almost useless in a 32-bit segment.  You might be able to use
"jecxz" instead, but it's slower than your test-and-jump approach.

>  The program crash and the trace of the stack don't say nothing about this
>routine.
>  I'm crazy? I'm dreaming? Any body saw some thing like this?

You're probably just seeing it jump to a location you didn't
expect.  "jcxz" will zero the top 16 bits of EIP when it jumps.

>2) In the GCC.INF manual under C Extensions says that:

>asm ("Scasb":::"%ecx","%edi");

Add spaces between colons.

.... " : : : " ...


>3) Another extention is:

>register int a asm ("%edx");

> And tells to GCC that "a" is the EDX register (cool :). But ....

> The following code:

>int pepe(void)
>{
> register int a asm ("%edx");

> a=0;
> asm ("Incl %%edx":::"%edx");

> return a;
>}


The extension of assigning a specific register has limited use
and in particular you can't expect to be able to change in it
assembler code without telling gcc about it.  You _might_ be
able to get away with specifying "memory" as being changed.

>4) If i put:

>asm ("Movw $0,%%es":::"%es"); (I don't want to do that is only an example ;)


See (1), but your asm statements must not change "es" anyway.
You may change "fs" and "gs" at will -- the compiler never uses
them.  libc does, though.


>   Then what things can i guess? Are true the following?:

>* ES=DS, at any time.

Only when you leave your asm ("...").  You can have tons of code
in there doing what they want to the segment registers.

>* GS and FS can be used for any function but this function *must* restore the
>original value before return (of course i exclude the farptr macros).

No need to restore.

>* EDI,ESI and EBX must be restored.

Either restored or gcc must be told that they're changed.  Again,
things get a lot better when you dump a bunch of instruction in
the same asm ("...").

>* ECX,EDX and EAX can be used.

As with other registers.

>* EAX is the return value.

Only count of this when you're writing everything in assembler.
(Having all the code of a C function being inline assembler is
not good enough.)

>  guess over guess:

>* If i alter ES, and don't restore the value, the program crash.

....at the next string instruction.




Morten

- Raw text -


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