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" 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