Hi,
I have a problem with 32-bit signed division. Below is a portion of the code having problem. In the following functions disassembly lines follows the source line.
****************************
******* Case1: **************
****************************
//source view
void RECEIVER_Div(void)
{
s_RxMaxPower = s_RxMaxPowerNr / s_RxMaxPowerDr;
}
//Mixed source/assembly view
void RECEIVER_Div(void)
{
line1: s_RxMaxPower = s_RxMaxPowerNr / s_RxMaxPowerDr;
line2: 3F34D2 761F MOVW DP,#0x0242
line3: 3F34D4 0610 MOVL ACC,@16
line4: 3F34D5 1E42 MOVL *-SP[2],ACC
line5: 3F34D6 060E MOVL ACC,@14
line6: 3F34D7 00FF FFC XAR7,UL$$DIV
line7: 3F34D9 1E08 MOVL @8,ACC
}
line8: 3F34DA 0006 LRETR
****************************
********* Case2 *************
****************************
//source view
void RECEIVER_UDiv(void)
{
s_uRxMaxPower = s_RxMaxPowerNr / s_RxMaxPowerDr;
}
//Mixed source/assembly view
void RECEIVER_UDiv(void)
{
line1: s_uRxMaxPower = s_RxMaxPowerNr / s_RxMaxPowerDr;
line2: 3F34DB 761F MOVW DP,#0x0242
line3: 3F34DD 0200 MOVB ACC,#0
line4: 3F34DE A30E MOVL P,@14
line5: 3F34DF F61F RPT #31 ||
line6: 3F34E0 5617 SUBCUL ACC,@16
line7: 3F34E2 A90A MOVL @10,P
}
line8: 3F34E3 0006 LRETR
****************************
*** Known Conditions *****
****************************
IDE: CCS (Version : 3.1.0)
Build Options-
Opt level : none
Program level opt: none
Stack Start : 0x0400
Stack Size : 0x0400
Data types of variables-
s_RxMaxPower 32 bit signed int
s_uRxMaxPower 32 bit unsigned int
s_RxMaxPowerNr 32 bit unsigned int
s_RxMaxPowerDr 32 bit unsigned int
***********************************
My problem is with Case1. In Case1, at line1 StackPointer(SP) points to 0x408(this is very well within the safe range, because we start from 0x400 and has a size of 0x400). After executing line4 we loss the value of next-old RPC(Return Program Counter) because the dinominator is pushed into the stack where the next-old RPC value is saved. So reffering to the below given portion of main() code, after returning from RECEIVER_Div() it will execute Process2() and Process3(), but it will never reach Process4() and then to Process5(). Rather it will go to the location pointed to by the value of s_RxMaxPowerDr. Because in Case1, after line4 we loose the address of Process4() which was in the stack.
***********************************
main()
{
Process1()
{
RECEIVER_Div();
Process2();
Process3();
}
Process4();
Process5();
}
***********************************
But in Case2 this not happens, because it is not using UL$$DIV and no need of the Denominator value to be pushed into the Stack.
We also noticed that if RECEIVER_Div() passes some prameters or if it has any local varible inside, this over-writting does not happen. Because a pair(32-bit) or more locations are initialized in the stack prior to entering in to RECEIVER_Div().
Q1. What is actually happening in Case1 as far as the Compiler is concerned?
Q2. Is it any problem with Compiler/Disassembler?
Q3. Is it due to we miss any math convention in coding?
Q4. How the compiler takes a 32-bit Division operation in which Numerator and Dinominator are Uint32 and the result has to be equated to an Int32 type varible?
-Any help is sincerely appriciated
--------
-Regards
-Sinoj