Please Help Me Understand 32-bit Multiplications in CW 5.7

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Please Help Me Understand 32-bit Multiplications in CW 5.7

ソリューションへジャンプ
1,559件の閲覧回数
GFSmith
Contributor II
Hello,

I'm using CodeWarrior 5.7, Build 2211 for the HCS12, specifically the MC9S12E128 microcontroller. 

The following compiler options are activated:

-CpPPAGE=0x30 -D_HCS12 -D__NO_FLOAT__ -Lasm=%n.lst -Lasmc=ehpv -Mb -Os -Onu -Onf -OnB -Onbf -Onbt -Onca -Oncn -OnCopyDown -OnCstVar -One -OnP -OnPMNC -Ont -Or -Rpe -WmsgSd1860

I have the following code:

#define ULONG          INT32U
#define TICKSPERMINUTE  0x00001770 /*Number of ticks per minute*/
.
.
static INT32U HexMins;
.
.
RtcDateTime.Minutes = 0x25;
 HexMins =  (RtcDateTime.Minutes)* TICKSPERMINUTE);

The result from the above calculation is HexMins = 0x6330, but it appears that the upper two bytes of the 32-bit value are being optimized away.

If I adjust the calculation as follows:
 HexMins =  (INT32U)(RtcDateTime.Minutes)* (INT32U)TICKSPERMINUTE);

Then I see the correct result HexMins = 0x36330.  It appears that casting both parts of the equation as 32-bit unsigned long are necessary to make things work.  Is this an optimization that I can adjust or turn off?

Thanks,
Greg Smith


ラベル(1)
タグ(1)
0 件の賞賛
返信
1 解決策
622件の閲覧回数
CompilerGuru
NXP Employee
NXP Employee
It's the language.
For C 0x00001770 has the same type as 0x1770, int. And multiplying ints results in a integer operation.
So either one of the two arguments has to be a long. The simplest way to make sure a constant is treated as long constant is to use an L at the end of the number. So 0x1770UL (unsigned long) will result in a 32 bit operation.

#define TICKSPERMINUTE  0x00001770UL /*Number of ticks per minute as unsigned long */

For details, ask google for "usual arithmetic conversions".

Daniel

元の投稿で解決策を見る

0 件の賞賛
返信
2 返答(返信)
622件の閲覧回数
GFSmith
Contributor II
That's what I needed to know, thanks!
G. Smith
0 件の賞賛
返信
623件の閲覧回数
CompilerGuru
NXP Employee
NXP Employee
It's the language.
For C 0x00001770 has the same type as 0x1770, int. And multiplying ints results in a integer operation.
So either one of the two arguments has to be a long. The simplest way to make sure a constant is treated as long constant is to use an L at the end of the number. So 0x1770UL (unsigned long) will result in a 32 bit operation.

#define TICKSPERMINUTE  0x00001770UL /*Number of ticks per minute as unsigned long */

For details, ask google for "usual arithmetic conversions".

Daniel
0 件の賞賛
返信