Mail Archives: djgpp/1996/05/11/09:05:53
"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 -