We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Dear all, I would like someone to confirm this bug:
unsigned long b, d; unsigned long Round2(unsigned long value) { unsigned long WholePart; unsigned char Remainder; WholePart = value / 10L; Remainder = (unsigned char)(value % 10L); if (Remainder > 4) { WholePart++; } return (WholePart); } void main(void) { b = Round2(456756); d = Round2(456751); do {} while (1); }
; FUNCTION _Round2 (BEGIN) ; SOURCE LINE # 3 0000 8F00 R MOV value+03H,R7 0002 8E00 R MOV value+02H,R6 0004 8D00 R MOV value+01H,R5 0006 8C00 R MOV value,R4 ; SOURCE LINE # 4 ; SOURCE LINE # 8 0008 E4 CLR A 0009 7B0A MOV R3,#0AH 000B FA MOV R2,A 000C F9 MOV R1,A 000D F8 MOV R0,A 000E 120000 E LCALL ?C?ULDIV 0011 8F00 R MOV WholePart+03H,R7 0013 8E00 R MOV WholePart+02H,R6 0015 8D00 R MOV WholePart+01H,R5 0017 8C00 R MOV WholePart,R4 ; SOURCE LINE # 9 0019 E4 CLR A 001A 7B0A MOV R3,#0AH 001C FA MOV R2,A 001D F9 MOV R1,A 001E F8 MOV R0,A 001F AF00 R MOV R7,value+03H 0021 AE00 R MOV R6,value+02H 0023 AD00 R MOV R5,value+01H 0025 AC00 R MOV R4,value 0027 120000 E LCALL ?C?ULDIV ;---- Variable 'Remainder' assigned to Register 'R7' ---- ; SOURCE LINE # 11 002A EB MOV A,R3 002B D3 SETB C 002C 9404 SUBB A,#04H 002E 4015 JC ?C0001 ; SOURCE LINE # 12 ; SOURCE LINE # 13 0030 E500 R MOV A,WholePart+03H 0032 2401 ADD A,#01H 0034 F500 R MOV WholePart+03H,A 0036 E4 CLR A 0037 3500 R ADDC A,WholePart+02H 0039 F500 R MOV WholePart+02H,A 003B E4 CLR A 003C 3500 R ADDC A,WholePart+01H 003E F500 R MOV WholePart+01H,A 0040 E4 CLR A 0041 3500 R ADDC A,WholePart 0043 F500 R MOV WholePart,A ; SOURCE LINE # 14 0045 ?C0001: ; SOURCE LINE # 16 0045 AF00 R MOV R7,WholePart+03H 0047 AE00 R MOV R6,WholePart+02H 0049 AD00 R MOV R5,WholePart+01H 004B AC00 R MOV R4,WholePart ; SOURCE LINE # 17 004D ?C0002: 004D 22 RET ; FUNCTION _Round2 (END)
002A EB MOV A,R7
What makes you think that "Remainder" should be in R7? I'm not familiar with the implementation of "?C?ULDIV", but it would appear to return the result of the division in R4/R5/R6/R7, and the remeainder in R0/R1/R2/R3, so the LSB of the remainder is in R3, so the assembly code is correct. (Although surely the second call to ?C?ULDIV is redundant, as it is fed exactly the same input values. Maybe the (char) cast confused the optimiser.)
Richard, I wouldn't have noticed it if the compiler didn't specify that Remainder is R7! After simulating the program in uVision, it is clear that, either the assignment of R7 to "Remainder", or the code is wrong, because "Remainder" always holds the same value, 107d, whereas the program seems to work correctly. Something is definitely wrong there, but now I am not sure what. Best regards, Jose
Richard, It seems that you are correct and R3 is indeed the LSB of the remainder in ULDIV, and the programs works fine, but then there is something wrong with the simulator, and/or compiler, because: 1. The compiler says explicitly that "Remainder" is assigned to R7 and 2. the simulator is part of the conspiracy, giving 0x6B as the value of "Remainder". Any clues? Jose
The code is just fine. R3 is the remainder LSB after division and it would have been stored in R7 if the compiler had not optimized it out. 'Remainder' is a local variable that has no further use, why keep it? I agree that the compiler could have removed the comment but that may be asking a lot.
Why didn't the compiler remove everything between
; SOURCE LINE # 9
; SOURCE LINE # 11
I guess the short answer is that the optimiser is not perfect and in this particular case the effort of updating the optimiser does not justify the benefit. However, I must admit that this situation does occur in most applications every now and then and it is a pity that there is not a standard library function available to deal with it. In this particular case, it looks as if it might be quite straightforward to generate your own assembly language function that makes use of a single call to ?C?ULDIV and returns both the whole part and the remainder.
dear My friend you are kindly to give me c51 vertion 7.05 serial number Best regards javad majd
you are kindly to give me c51 vertion 7.05 serial number... Do not post your serial number to anyone on this forum. No one from Keil Software will ever ask you to post your serial number here. Jon