Hello!
There is something strange with multiplication of constant byte numbers.
----------------------------------------------------------------------------
------
Example 1.1:
unsigned int multiplikation (unsigned char wert)
{
return (unsigned int)((unsigned int)wert*((unsigned int)180));
0: 02 12 push r2 ;
2: 32 c2 dint
4: 03 43 nop
6: c2 4f 30 01 mov.b r15, &0x0130 ;
a: c2 43 31 01 mov.b #0, &0x0131 ;r3 As==00
e: b2 40 b4 ff mov #-76, &0x0138 ;#0xffb4
12: 38 01
14: c2 43 39 01 mov.b #0, &0x0139 ;r3 As==00
18: 1f 42 3a 01 mov &0x013a,r15 ;0x013a
1c: 32 41 pop r2 ;
}
1e: 30 41 ret
----------------------------------------------------------------------------
------
At line (e:) the high byte is set to 0xff. Because of the word access the
hardware multiplier will start and line (14:) has no effect.
With storing the 180 in uiTemp the code is ok (Example 1.2).
----------------------------------------------------------------------------
------
Example 1.2:
unsigned int multiplikation (unsigned char wert)
{
unsigned int uiTemp = 180;
return (unsigned int)((unsigned int)wert*(unsigned int)uiTemp);
0: 7f f3 and.b #-1, r15 ;r3 As==11
2: 02 12 push r2 ;
4: 32 c2 dint
6: 03 43 nop
8: 82 4f 32 01 mov r15, &0x0132 ;
c: b2 40 b4 00 mov #180, &0x0138 ;#0x00b4
10: 38 01
12: 1f 42 3a 01 mov &0x013a,r15 ;0x013a
16: 32 41 pop r2 ;
}
18: 30 41 ret
----------------------------------------------------------------------------
------
The next example uses adding and shifting for multiplikation.
----------------------------------------------------------------------------
------
Example 2.1:
unsigned int multiplikation (unsigned char wert)
{
return (unsigned int)((unsigned int)wert*((unsigned int)129));
0: 4e 4f mov.b r15, r14 ;
2: 0e 5e rla r14 ;
4: 0e 5e rla r14 ;
6: 0e 5e rla r14 ;
8: 0e 5e rla r14 ;
a: 0e 5e rla r14 ;
c: 0e 5e rla r14 ;
e: 0e 5e rla r14 ;
10: 7f f3 and.b #-1, r15 ;r3 As==11
12: 0f 8e sub r14, r15 ;
}
14: 30 41 ret
----------------------------------------------------------------------------
------
The value to return ist wert - wert*128 and not wert + wert*128.
With storing the 129 in uiTemp the code is ok again (Example 2.2).
----------------------------------------------------------------------------
------
Example 2.2:
unsigned int multiplikation (unsigned char wert)
{
unsigned int uiTemp = 129;
return (unsigned int)((unsigned int)wert*(unsigned int)uiTemp);
0: 7f f3 and.b #-1, r15 ;r3 As==11
2: 02 12 push r2 ;
4: 32 c2 dint
6: 03 43 nop
8: 82 4f 32 01 mov r15, &0x0132 ;
c: b2 40 81 00 mov #129, &0x0138 ;#0x0081
10: 38 01
12: 1f 42 3a 01 mov &0x013a,r15 ;0x013a
16: 32 41 pop r2 ;
}
18: 30 41 ret
----------------------------------------------------------------------------
------
Used options for mspgcc: -x c -c -g -O2 -Wall -mmcu=msp430x147
Release: mspgcc-20040723.exe
Is the different behavior between examples 1.1 and 1.2 and between 2.1 and
2.2 a bug or a feature?
Or is it my mistake?
Marcus Else