Randal E. Bryant and David R. O'Hallaron
CS:APP Home Page
On page 228 of CS:APP we stated that with GCC's inline assembly "...there are no direct ways to specify a program value to use as the destination operand for the setae instruction, since the operand must be a single byte." In fact, you can specify single-byte operands with gcc by declaring variables of type char. This allows us to simplify the inline assembly for ok_smul3 (p. 227) to the following (called ok_smul4):
int ok_smul4(int x, int y, int *dest)
{
unsigned char byte_result;
*dest = x*y;
/* Insert the following assembly code:
setae byte_result # Set result
*/
asm("setae %0"
: "=r" (byte_result) /* Output */
);
return (int) byte_result;
}
Similarly, here's a simplified version of ok_umul (called ok_umul2):
int ok_umul2(unsigned x, unsigned y, unsigned *dest)
{
unsigned char byte_result;
/* Insert the following assembly code:
movl x,%eax # Get x
mull y # Unsigned multiply by y
movl %eax, *dest # Store low-order 4 bytes at dest
setae byte_result # Set result
*/
asm("movl %2,%%eax; mull %3; movl %%eax,%0; setae %1"
: "=r" (*dest), "=r" (byte_result) /* Outputs */
: "r" (x), "r" (y) /* Inputs */
: "%eax" /* Overwrites */
);
return (int) byte_result;
}
Thanks to Michael Trigoboff for
showing us this trick.