Question

I am currently studying for an exam, but I ordered my own Arduino kit and want to learn more about this on my own.

I'm studying MULSU and MULS for this class. Here's an example he gave us:

LDI r16, 150
LDI r17, 10
MULS r16, r17

;-106 * 10 = -1060
;R1:R0 = 0xFB:0xDC

What I don't understand is why we don't take the two's complement of 10, but we do take the two's complement of 150. I thought, since they're both signed, we would take the two's complement of both and then multiply. Does a number, if within a certain range, not have to be changed if it's signed? I have noticed this applied a lot in AVR, and I feel like it's something I need to understand in order to gain skill in the area.

Thank you

Was it helpful?

Solution

I'm assuming we're dealing with 8-bit registers here.

Both numbers you mentioned can be encoded by the bitvector 10010110. When you read it as an unsigned number, it means 150. When you read it as a two's complement signed number, it means -106.

Does a number, if within a certain range, not have to be changed if it's signed?

Good question. To see what's going on, you might want to list all possible bitvectors of length eight, and try to interpret them as unsigned and signed numbers:

         unsigned signed
00000000        0      0
00000001        1      1
00000010        2      2
...
01111101      125    125
01111110      126    126
01111111      127    127
10000000      128   -128
10000001      129   -127
10000010      130   -126
...
11111101      253     -3
11111110      254     -2
11111111      255     -1

The range you have for unsigned integers is 0 .. 255, and for two's complement signed numbers it's -128 .. 127. But as you see, as long as the most significant bit is 0, the unsigned interpretation and the signed interpretation are identical.

So, to hint to an answer to you question:

What I don't understand is why we don't take the two's complement of 10, but we do take the two's complement of 150.

I think the assembly language you use doesn't allow you to write signed numbers. The intention is to multiply -106 and 10, as indicated in your teacher's comments, but the assembler may only understand unsigned numbers. That's why you're writing unsigned numbers that have the same encoding as the (intended) signed numbers. For -106, that happens to be 150 (both are encoded as 10010110), and for 10, that happens to be 10 (both are encoded as 00001010).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top