-3

In ARM Assembly each register can contain 32 bits/1 word of information stored in it. That's why when you try to store a value larger than 255 it gives you an error

However, the MUL instruction seems to not have this limitation. You can multiply two registers, each of them having the value of 255 for instance, and store the result in a third register without any errors. How does this happen? Shouldn't the destination register be unable to store values beyond 255?

  • 3
    255 is an unsigned *byte*, 8 bits. Perhaps is you show us some code, together with the errors you have, so we can explain what's going on and actually help you. – Some programmer dude Oct 23 '16 at 06:21
  • We assume you are referring to a 32-bit ARM arch; however, there are 64-bit ARMv8 units out there; e.g., Cortex-A53, A57. Nonetheless, if we assume a 32-bit general purpose register then trying to do something like mov r1,#0xfffffffff would result in an invalid constant error during compile. Otherwise, doing an add or mul of numbers like 0xffffffff would certainly result in an overflow and if you do not account for that in your code your result would be construed by others as an "error", mathematically speaking. As @dwelch indicated, 2^32 * 2^32 = 2^64. You'll need more registers in such cases – InfinitelyManic Oct 25 '16 at 15:45
  • I'm voting to close this question as off-topic because it would be better asked to http://softwareengineering.stackexchange.com – Seki Nov 01 '16 at 13:53

1 Answers1

1

32 bits has a maximum size of 0xFFFFFFFF (about 4 billion) so 0xFF (which is 255) times 0xFF is 0xFE01 (65025) which is much less than 4 billion.

You do raise an interesting topic, which is that you can't multiply 0xFFFFFFFF x 0xFFFFFFFF without overflowing. I don't believe "it gives you an error", it just truncates the result.

Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
  • 1
    The ARM `mul` instruction is explicitly defined as yielding the least-significant 32 bits of the result, though (and as a result doesn't need to worry about the signed/unsigned distinction), which probably makes the matter somewhat less interesting. – Notlikethat Oct 23 '16 at 11:04
  • From gradeschool we remember that (x^2) * (x^3) = x^(2+3). So think of x as 2, binary. If you were to multiply 2^31 * 2^31, right away you end up with 2^62 which is an overflow, and then you have to think about is it possible to carry over beyond that. And the 0xFF * 0xFF and any other all ones times all ones for an unsigned multiply with your calculator except maybe 1 * 1 or other small numbers like that, are going to overflow one more bit. So in the case of 0xFF * 0xFF our msbits are 2^7 giving us 2^14 carry over one more 2^15 takes 16 bits to store that result. – old_timer Oct 25 '16 at 03:06
  • most of the combinations of 32 bit operands wont fit in a 32 bit result for an unsigned multiply. Has absolutely nothing to do with assembly nor arm. We know this from C or other languages, and it is true for any other instruction set that has a multiply with the same sized result. I would also expect a similar situation for signed multiply. At least one ARM ARM shows the flags affected are N and Z, so there is no indication of overflow, you just have to deal with it just like you deal with it in high level languages. – old_timer Oct 25 '16 at 03:11