0

I have to do 5 byte signed Int square. For example, I made a 5 byte random signed interger, and then want to know square these random signed interger at assembly lang. In x86-32 and MASM assembler, They does not support over the 32bit. So I meet trouble that square of it. We can use Irvine32 library, and below pic is the Irvine32 library list.Irvine32 library Please help me how to square these random 5byte signed interger.

Maybe, I think 5byte divide into 4 byte and 1byte to square it. But I don't know how to do it.

I don't know the algorithm that made signed integer square

HJH
  • 11
  • 1
    See the [linked duplicate](https://stackoverflow.com/a/24238871/547981) with the special case of `x = y` – Jester Jun 05 '23 at 13:28
  • @Jester Squaring 5 bytes integer is simpler than generic 64-bit multiplication. I prepared the answer but question is already closed. Voting for reopen. – dimich Jun 05 '23 at 14:16
  • 1
    Since the question is closed i'll give the hint here. First, square is always non-negative. Take absolue value of argument and use unsigned multiplication. Second, 5-byte integer may be represented as two integers: `N = H*2³² + L`, where H and L are high and low parts respectively. Thus `N² = H²*2⁶⁴ + 2*2³²*H*L + L²`. Calculate `L*L`, store 64-bit result to memory. Calculate `H*L`, then multiply by 2 (probably using shift) and add low 32-bit word to millde 32-bit word of stored result, add carry to high bits and store to result. Calculate `H*H` and add 16 bits to high 16-bit word of result. – dimich Jun 05 '23 at 18:05
  • @dimich: Good point about needing to take the absolute value if you want a 10-byte full product. The low x high cross product then need to be widening unsigned x signed, and there's no instruction to do that, only `mul` and `imul`. We can sign-extend H to 32-bit instead of zero-extend like in their previous almost-identical question about unsigned, but the high half of the product would be wrong if L had it's MSB set. – Peter Cordes Jun 05 '23 at 18:16
  • The duplicate @Jester linked does non-widening 64x64 => 64-bit multiply, so for that you would just sign-extend H to 32-bit. The OP hasn't specified what width of result they want, so dimich's full version might not be needed. (It's also an unusual input size; makes me wonder if it's really a 40-bit integer or a 5-decimal-digit number stored in 5 ASCII bytes of input. Especially since they're using Irvine32 which only has I/O helper functions for 32-bit integers, I think.) – Peter Cordes Jun 05 '23 at 18:23
  • @PeterCordes We don't need unsigned x signed. Assuming 5-byte argument is two's complement, entire value is negative if `H` is negative. Extend `H` to signed 32-bit value, then `neg low_part; adc high_part,0; neg high_part`. This will negate the argument and it may be multiplied by itself as unsigned. – dimich Jun 05 '23 at 18:26
  • 1
    @dimich: I meant if you were going to do it *without* conditionally negating to take the absolute value first. If you don't need a widening multiply, you don't need to abs(). But if you do, then yes, abs() before squaring is presumably more efficient than emulating unsigned x signed multiply. – Peter Cordes Jun 05 '23 at 18:28

0 Answers0