c - GCC Inline Assembly Multiplication -


i'm trying learn gcc inline assembly on linux (x86), , first experiment try , implement integer overflow detection multiplication. seems easy enough, having side effects don't understand.

so, here want multiply 2 unsigned 8-bit integers, , see if result overflows. load first operand al register , other operand bl register, , use mul instruction. result stored 16-bit value in ax register. copy value in ax register c variable b, unless overflows. if overflows set c 1.

 uint8_t = 10;  uint8_t b = 25;  uint8_t c = 0; // carry flag   __asm__  (   "clc;"                  // clear carry flag   "movb %3, %%al;"        // load b %al   "movb %2, %%bl;"        // load %bl    "mul %%bl;"             // multiply * b (result stored in %ax)   "movw %%ax, %0;"        // load result b   "jnc out;"              // jump 'out' if carry flag not set   "movb $1, %1;"          // set 'c' 1 indicate overflow   "out:"   :"=m"(b), "=m"(c)       // output list   :"ir"(a), "m"(b)        // input list   :"%al", "%bl"           // clobbered registers (not sure this)  ); 

this seems work fine. if printf value of 'b' 250, correct. also, if change starting value of 'b' 26, after multiplication c set 1, indicating overflow because of course (10 * 26 > ~uint8_t(0)). problem i'm seeing c variable a set 0 after multiplication (or 1 on overflow.) don't understand why a changed @ i'm doing here. it's not on list of output variables, why assembly routine affecting value of a?

also, i'm unsure clobbered registers list. list supposed inform gcc registers used during assembly routine, gcc doesn't try use them incorrectly. think need inform gcc used al , bl registers, ax register? it's used implicitly store product of 2 8-bit integers, need include in list of clobbered registers?

the problem i'm seeing c variable a set 0 after multiplication (or 1 on overflow.) don't understand why a changed @ i'm doing here. it's not on list of output variables, why assembly routine affecting value of a?

mul %%bl multiplies al (8 bits) bl (8 bits), placing result in ax (16 bits).

note al , ax not separate registers: al bottom 8 bits of ax.

movw %%ax, %0 stores ax (16 bits) address of b... uint8_t. instruction overwriting next byte in memory top 8 bits of result. in case, byte happens value of a stored (which explains why a overwritten 0 when doesn't overflow, , 1 when does).

you need replace movb %%al, %0, byte store of bottom 8 bits of result.

i think need inform gcc used al , bl registers, ax register? it's used implicitly store product of 2 8-bit integers, need include in list of clobbered registers?

yes - should tell gcc register change value of (and, nategoose pointed out in answer, should tell you're changing flags well). clobber list here should "%ax", "%bl", "cc" (ax includes al, don't need mention al explicitly).


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -