Keil™, An ARM® Company

Technical Support

C51: 16-BIT MULTIPLY WITH 32-BIT RESULT


Information in this article applies to:

  • C51 Version 5.50a
  • C51 Version 6.12

QUESTION

Is it possible to multiply two 16-bit numbers (without casting them to long) and get a 32-bit result?

ANSWER

This is not accounted for in the C language specification.

However, the following assembler function does this math operation:

NAME    MULT

?PR?_uint_mult?MULT  SEGMENT CODE
        PUBLIC  _uint_mult

        RSEG  ?PR?_uint_mult?MULT
_uint_mult:
; x stored in R6+R7
; y stored in R4+R5

          mov     a,r7
          mov     b,r5
          mul     ab      ; ab = R7*R5

          mov     r3,b
          xch     a,r7    ; a = R7

          mov     b,r4
          mul     ab      ; ab = R4*R7

          add     a,r3
          mov     r3,a
          mov     a,#0
          addc    a,b
          xch     a,r5    ; a = R5

          mov     b,r6
          mul     ab      ; ab = R5*R6

          add     a,r3
          xch     a,r6

          xch     a,b     ; b = R6

          addc    a,r5
          mov     r5,a
          mov     a,#0
          addc    a,#0
          xch     a,r4

          mul     ab      ; ab = R4*R6

          add     a,r5
          mov     r5,a
          mov     a,b
          addc    a,r4
          mov     r4,a

; Result returned in R4+R5+R6+R7

        RET

        END

You must prototype this routine in your C code as follows:

unsigned long uint_mult (
  unsigned int x,
  unsigned int y);

and use it as follows:

unsigned long z;
unsigned int x, y;

unsigned long z1;

for (x = 0; x < 0xFF00; x += 13)
  {
  for (y = 0; y < 0xFF00; y += 17)
    {
    z1 = (unsigned long) x * y;
    z = uint_mult (x, y);

    if (z != z1)
      {
      printf ("0x%4.4X x 0x%4.4X = ", x, y);
      printf ("0x%8.8LX (0x%8.8LX)\n", z, z1);
      }
    }
  }

Last Reviewed: Sunday, July 29, 2001


Did this article provide the answer you needed?
 
Yes
No
Not Sure