This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

printf repairs corrupted long long arithmetic

take a look to my programm:
When counting how often a unsigned long long integer could be divided by ten, i got strange results. Then i realised, a printf function call repairs the fault.
Who can explain the strange effect?

//-------------------------------------------------------------------
// a little C Programm (CARM) just to demonstrate:
// printf function call repairs corrupted long long arithmetic..
//
//           sometimes i awake in the middle of the night
//                        sweat flooded
//                 my heart beating like a drum
//        is C just an abbreviation for Crashing airplanes?
//-------------------------------------------------------------------
#include <ADuC7026.h>
#include"stdio.h"

void RS232_init(int);
int main (void)
{
	unsigned long long int A;
	unsigned int n;

	RS232_init(9600);
	while(1)
	{
		printf("\nStart\n");

		A=100000000000000;
		n=0;
		while(A)
		{
			printf("");
			n++;
			A /= 10;
		}
		printf("%d \n",n);	//expected 15, got 15

		A=100000000000000;
		n=0;
		while(A)
		{
			n++;
			A /= 10;
		}
		printf("%d \n",n);	//expected 15, got 2

		printf("\nPress a key\n");
		scanf("%*c");
	}
}

void RS232_init(int Baudrate)
{
							// 3% error on 115200 Baud !!!
	GP1CON  = 0x011;		// Setup tx & rx pins on P1.0 and P1.1
   	COMCON0 = 0x080;		// Setting DLAB
							// Setting DIV0 and DIV1 to DL calculated
   	COMDIV0 = 32768*1275/32/Baudrate;
   	COMDIV1 = 0x000;
   	COMCON0 = 0x007;		// Clearing DLAB
}


Parents Reply Children
  • Yes, a look to the assembler code is a good idea. ;-)

    Making n volatile does'nt change a thing.
    Making A volatile changes result n from two to one. (15 expected) So volatile has an effect.

  • looking to assembler code is an endless story...
    for example:

                     ?C?UQDIV?A:
    0x0008102C  E92D00F0  STMDB     R13!,{R4-R7}
    0x00081030  E3A0C040  MOV       R12,#0x00000040
    0x00081034  E2626000  RSB       R6,R2,#0x00000000
    0x00081038  E2E37000  RSC       R7,R3,#0x00000000
    0x0008103C  E3A02000  MOV       R2,#0x00000000
    0x00081040  E0923002  ADDS      R3,R2,R2
    0x00081044  E0B00000  ADCS      R0,R0,R0
    0x00081048  E0B11001  ADCS      R1,R1,R1
    0x0008104C  E0B22002  ADCS      R2,R2,R2
    0x00081050  E0A33003  ADC       R3,R3,R3
    0x00081054  E0924006  ADDS      R4,R2,R6
    0x00081058  E0B35007  ADCS      R5,R3,R7
    0x0008105C  21A02004  MOVCS     R2,R4
    0x00081060  21A03005  MOVCS     R3,R5
    0x00081064  E24CC001  SUB       R12,R12,#0x00000001
    0x00081068  E11C000C  TST       R12,R12
    0x0008106C  1AFFFFF4  BNE       0x00081044
    0x00081070  E0B00000  ADCS      R0,R0,R0
    0x00081074  E0B11001  ADCS      R1,R1,R1
    0x00081078  E8BD00F0  LDMIA     R13!,{R4-R7}
    0x0008107C  E12FFF1E  BX        R14
    
    the "MOVCS R2,R4" instruction doesn't do the expected:
    while R4=0xFFFFFFF6 the result in R2=0x044CDA92.
    Same with "MOVCS R3,R5"

    Who can help?