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 whya
changed @ i'm doing here. it's not on list of output variables, why assembly routine affecting value ofa
?
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
Post a Comment