From: buers AT gmx DOT de (Dieter Buerssner) Newsgroups: comp.os.msdos.djgpp Subject: Re: 'retf' in inline? Date: 9 Apr 2000 19:00:32 GMT Lines: 131 Message-ID: <8cqr46.3vs4f8r.0@buerssner-17104.user.cis.dfn.de> References: <38EFFFE0 DOT B217D192 AT home DOT com> <38F02F72 DOT A7C88440 AT mtu-net DOT ru> NNTP-Posting-Host: pec-105-91.tnt5.s2.uunet.de (149.225.105.91) Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Trace: fu-berlin.de 955306832 7026263 149.225.105.91 (16 [17104]) X-Posting-Agent: Hamster/1.3.13.0 User-Agent: Xnews/03.02.04 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Alexei A. Frounze wrote: A few comments to your ASM guide. > [GOTCHA!] ] Opcode prefixes should NOT be written on the same line as the >instruction they act upon. For example, "rep" and "stosd" should be two >separate instructions, but the latter immediately following the former. You could mention, that instead of writing "rep\n" "stosd\n" one can also write "rep; stosd\n" At least, this form is more pleasing to my eyes ;) > int i = 0; > __asm__(" > pushl %%eax\n > movl %0, %%eax\n > addl $1, %%eax\n > movl %%eax, %0\n > popl %%eax" > : > : "g" (i) > ); > /* i++; */ This may produce wrong code, becauce gcc has no way to know, that i is modified by the inline assembly. Note, that gcc does not try interprete the asm code. So, if you use i again after your asm instruction, gcc may assume, that it is still zero. >Don't panic yet! =) I'll try to explain first. Our input variable is "i" >and we want to increment it by 1. We don't have any output variables, nor But you should have an output variable. >might even optimize it!). Other commonly used constraints are "r" (load >into any available register), "a" (ax/eax), "b" (bx/ebx), "c" (cx/ecx), >"d" (dx/edx), "D" (di/edi), "S" (si/esi), etc. You might want to mention "q" for one of eax/ebx/ecx/edx as well. >Let's do two inputs and introduce "volatile": > > int i=0, j=1; > __asm__ __volatile__(" > pushl %%eax\n > movl %0, %%eax\n > addl %1, %%eax\n > movl %%eax, %0\n > popl %%eax" > : > : "g" (i), "g" (j) > ); > /* i = i + j; */ This may produce wrong code as well. With your code gcc is free to allocate register eax for variable j. The line addl %1, %%eax\n will then be translated to addl %eax, %eax by gcc. > [GOTCHA!] ] Oh yeah, what exactly is this "volatile" thing? It just >prevents the compiler from modifying your asm statements (reordering, >deleting, combining, etc.), and assemble them as they are (yes, gcc will >optimize if it feels like it!). Gcc won't modify asm statements. It can reorder, delete ... asm instructions (from asm(... up to the closing ). > int i=0, j=1, k=0; > __asm__ __volatile__(" > pushl %%eax\n > movl %1, %%eax\n > addl %2, %%eax\n > movl %%eax, %0\n > popl %%eax" > : "=g" (k) > : "g" (i), "g" (j) > ); > /* k = i + j; */ Here you have the same problem as above. If either j or k are allocated to register eax by gcc, the code won't work. > int i=0, j=1, k=0; > __asm__ __volatile__(" > movl %1, %%eax\n > addl %2, %%eax\n > movl %%eax, %0" > : "=g" (k) > : "g" (i), "g" (j) > : "ax", "memory" > ); > /* k = i + j; */ Why have you put "memory" into the clobber list. This is not needed here. What could be needed is "cc" for condition code. This would tell gcc, that your code will modify the flags. (But AFAIK gcc for x86 will always assume, that the flags get modified. Who knows, when this will change ...) > [GOTCHA!] ] If we are also touching memory (writing to vars, etc.), it's >recommended to specify '"memory"' in the registers-modified field. This You don't need "memory", when you modify a variable. You need memory when i.e. a variable is a pointer, and you modify the memory where it points to. A typical example would be a memmove/memcopy implementation. Also, an other example, that shows how to write code for clobbered input registers might be useful here. At least you should mention, that an input register may not be in the clobber list. Finally, an example the shows what to do when you need an register as input and output could be helpful. -- Regards, Dieter