Hi.

I wrote a small function for my atmega32 uc in asm code that multiplies two signed numbers.

The code is similar to this one over here [1]

I debugged the code and it works, but I didn't understand the sbc part.

Why do i have to substract the carry from the highest written register before adding each partial product (except the first and the last ones) to the corespondent registries ?

The teacher told something about the extension of each partial product , that it should be completed with zeros for unsigned products and the sign bit for signed products. But I know that C2 numbers don't have a sign bit, so I'm confused.

Thanks in advance for any explanation.

[1] http://support.atmel.no/knowledgebase/avrstudiohelp/mergedProjects/AVRASM/Html/MULSU.html

I wrote a small function for my atmega32 uc in asm code that multiplies two signed numbers.

The code is similar to this one over here [1]

I debugged the code and it works, but I didn't understand the sbc part.

Why do i have to substract the carry from the highest written register before adding each partial product (except the first and the last ones) to the corespondent registries ?

mulsu r23, r20 ; (signed)ah * bl

sbc r19, r2

add r17, r0

adc r18, r1

adc r19, r2

The teacher told something about the extension of each partial product , that it should be completed with zeros for unsigned products and the sign bit for signed products. But I know that C2 numbers don't have a sign bit, so I'm confused.

Thanks in advance for any explanation.

[1] http://support.atmel.no/knowledgebase/avrstudiohelp/mergedProjects/AVRASM/Html/MULSU.html

bump

i guess my topic wasn't too visited due to the timezone difference

i guess my topic wasn't too visited due to the timezone difference

Well, I don't know anything about Atmel, and I don't know what you mean by 'C2 numbers'.

But other than that... I suppose what the teacher means is that this is an extended multiply routine.

It combines a number of smaller multiply operations and accumulates these results to multiply a larger number than what the CPU's own instructions are capable of.

By the looks of it, the mulsu multiplies two byte-sized operands and returns a 16-bit result. The entire routine is for multiplying two 16-bit operands into a 32-bit result.

The partial products produced by mulsu will only be 16-bit, but you need to accumulate them into the 32-bit result. So, you need to extend the sign into the full 32-bits before you accumulate.

I hope that makes sense.

Edit: Oh, I think with C2 you mean "two's complement"?

You're right, technically they don't have a sign bit. However, they DO have the characteristic that if the most significant bit is set, that the number is then negative.

For this reason people sometimes refer to the most significant bit as the sign bit (not entirely correct, but usually it makes sense from the context).

What it boils down to is basically that all the top bits are set for negative numbers.

In general, you can produce -n from n by inverting all bits in n, and then adding 1.

So in the case of -1, for 8 bits...

You have 1: 00000001

Then you invert all bits: 11111110

Then you add 1: 11111111

Now, if you want a 16-bit version of -1, it would instead look like this:

1111111111111111

The general rule for extending two's complement is this: If the most significant bit is set, then the extended bits in the larger number also need to be set. And conversely, if the most significant bit is clear, the extended bits also need to be clear.

So that's why the 'sign bit' needs to be extended for signed products.

But other than that... I suppose what the teacher means is that this is an extended multiply routine.

It combines a number of smaller multiply operations and accumulates these results to multiply a larger number than what the CPU's own instructions are capable of.

By the looks of it, the mulsu multiplies two byte-sized operands and returns a 16-bit result. The entire routine is for multiplying two 16-bit operands into a 32-bit result.

The partial products produced by mulsu will only be 16-bit, but you need to accumulate them into the 32-bit result. So, you need to extend the sign into the full 32-bits before you accumulate.

I hope that makes sense.

Edit: Oh, I think with C2 you mean "two's complement"?

You're right, technically they don't have a sign bit. However, they DO have the characteristic that if the most significant bit is set, that the number is then negative.

For this reason people sometimes refer to the most significant bit as the sign bit (not entirely correct, but usually it makes sense from the context).

What it boils down to is basically that all the top bits are set for negative numbers.

In general, you can produce -n from n by inverting all bits in n, and then adding 1.

So in the case of -1, for 8 bits...

You have 1: 00000001

Then you invert all bits: 11111110

Then you add 1: 11111111

Now, if you want a 16-bit version of -1, it would instead look like this:

1111111111111111

The general rule for extending two's complement is this: If the most significant bit is set, then the extended bits in the larger number also need to be set. And conversely, if the most significant bit is clear, the extended bits also need to be clear.

So that's why the 'sign bit' needs to be extended for signed products.

I understand how the C2 numbers are extended, but I don't get the way this extension is obtained from the following code

How is the carry indicator calculated after the multiply instruction?

The partial product on this code is in R18:R17. How is the extension obtained in R19 only by subtracting this carry?

If the carry is 0, then R19 remains unchanged, which means extension is ..0000

If the carry is 1, then R19=R19-1, how does that make the extension 1111... ?

On wikipedia it's presented the Booth's algorithm, but I see it's different from my problem as I don't need to compare adjacent bits at every step, still my program does the multiplication correctly.

mulsu r23, r20 ; (signed)ah * bl

sbc r19, r2 ;r2 is a clear register (0000 0000)

add r17, r0

adc r18, r1

adc r19, r2

How is the carry indicator calculated after the multiply instruction?

The partial product on this code is in R18:R17. How is the extension obtained in R19 only by subtracting this carry?

If the carry is 0, then R19 remains unchanged, which means extension is ..0000

If the carry is 1, then R19=R19-1, how does that make the extension 1111... ?

On wikipedia it's presented the Booth's algorithm, but I see it's different from my problem as I don't need to compare adjacent bits at every step, still my program does the multiplication correctly.

0 - 0 = 0.

0 - 1 = -1.

And as we know, -1 in two's complement notation is 11111111.

So this extends the carry flag to the entire register.

If you look at the mulsu instruction specification, you see that it sets carry to bit 15 of the result. Which is exactly what we want.

0 - 1 = -1.

And as we know, -1 in two's complement notation is 11111111.

So this extends the carry flag to the entire register.

If you look at the mulsu instruction specification, you see that it sets carry to bit 15 of the result. Which is exactly what we want.

Thanks Scali.