Date: Sat, 1 Nov 1997 10:16:37 -0800 (PST) Message-Id: <199711011816.KAA18640@adit.ap.net> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" To: djgpp AT delorie DOT com From: Nate Eldredge Subject: Re: Errors in once program Content-Transfer-Encoding: 8bit Precedence: bulk At 02:54 10/31/1997 EST, VANGEL AT vmredipn DOT ipn DOT mx wrote: >Hi ... >I run the fellow program: > >/*******************************************************************/ > >#include >#include > >void square( unsigned long *a, unsigned long *b ) >{ > /* This function squares a 48-bit number "a" into a > 96 bit number "b", stored in binary and in little- > endian order. */ > > __asm__ (" > movl (%0), %%eax \n > mull %%eax \n > movl %%eax, (%1) \n > movl 4(%0), %%eax \n > mull %%eax \n > movl %%eax, 8(%1) \n > movl %%edx, 4(%1) \n > movl 4(%0), %%eax \n > mull (%0) \n > addl %%eax, %%eax \n > adcl %%edx, %%edx \n > addl %%eax, 4(%1) \n > adcl %%edx, (%1) \n" > : > : "g"(a), "g"(b) > : "%eax", "%edx", "memory"); >} > >/*---------------------------------------------------------------------*/ > >int main(int argc,char *argvŲ){ > unsigned long b3Ų,a2Ų; > > a0Ų=atol(argv1Ų); > a1Ų=atol(argv2Ų); > > square(a,b); > > printf("%.8x %.8x %.8x\n\n", b0Ų, b1Ų, b2Ų); > return 0; >} >---------------------------------------------------------------------------- > >And I get the fellow errors : > >C:\TC\ASMG>gcc -Wall pp1.c -o pp11.exe >pp1.c: In function `main': >pp1.c:42: warning: unsigned int format, long unsigned int arg (arg 2) >pp1.c:42: warning: unsigned int format, long unsigned int arg (arg 3) >pp1.c:42: warning: unsigned int format, long unsigned int arg (arg 4) The reason for that is your printf() format arguments. It's not really a problem on DJGPP, where `unsigned int' and `long unsigned int' are the same, but you should probably change it to "%.8lx", if I remember correctly. >C:\djgpp\tmp\cccaaaaa: Assembler messages: >C:\djgpp\tmp\cccaaaaa:12: Error: Missing ')' assumed >C:\djgpp\tmp\cccaaaaa:12: Error: Ignoring junk '(%ebp))' after expression [and so on] Okay. The problem here is that you have pointer variables set up as a "g" operand. Since they're already on the stack, the compiler substitutes in their address, like `8(%ebp)'. It doesn't know that you are trying to use it indirectly, so the assembler output looks like: movl (8(%ebp)), eax which is clearly wrong. You are trying to do double indirection with one instruction, which the processor can't do. So how do you fix it? Offhand, I can see two possibilities. 1. Have the compiler load the arguments `a' and `b' into registers. You could do this by specifying an "r" constraint, but then it might use a register that you use for something else, causing problems. You could explicitly put them in registers you aren't using, like ESI and EDI, by using the "S" and "D" constraints. 2. Be aware that a pointer may be used, and use one `mov' to get the pointer into a register, then use that as your variable. I.E.: movl %0, %%esi # or some other register you can spare movl (%%esi), %%eax Don't forget to add any other registers you use to the "clobber" list. Nate Eldredge eldredge AT ap DOT net