This is a bug that I came across myself a few days back, but hadn't released a fix for yet. The problem was with the negate operator, which is meant to invert the variable and add one, but which wasn't adding one on AVR.
pat, that code looks ok. The compiler uses Two's complement, which requires inverting and adding. So, if we negate 127, first we invert, which gives 65408 (or 0xFF80), then we add one and that gives 65409, or 0xFF81.
As an example of why that works, suppose that we're adding 200 to -127. The result should be 73. If we add 200 to 65409, that gives 65609, which overflows to 73 (65609 AND 65535 = 73).
(Please do point out anything that looks like a bug, I'd rather explain how something works than have bug hiding in the compiler!)
Last edit: Hugh Considine 2014-10-30
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for your quick answer.
I'll never speak about bug now. ;-)
this is the function ABS in ASM;
FN_ABS:
;If SysCalcTempA.15 Then
sbrs SYSCALCTEMPA_H,7
rjmp ELSE1_1
;Abs = -SysCalcTempA
com SYSCALCTEMPA
sts ABS,SYSCALCTEMPA
com SYSCALCTEMPA_H
sts ABS_H,SYSCALCTEMPA_H
inc ABS
brne PC + 2
inc ABS_H
;Else
rjmp ENDIF1
ELSE1_1:
;Abs = SysCalcTempA
sts ABS,SYSCALCTEMPA
sts ABS_H,SYSCALCTEMPA_H
;End If
ENDIF1:
ret
In case SYSCALCTEMPA_H bit is 1 , that a negative number
we make a COM function on the 2 bytes and put the result in SYSCALCTEMPA_H and SYSCALCTEMPA_L
then copy on ABS and ABS_H
OK
Then ,we increment ABS and ABS_H for to correct that you explain on the previous post
it is OK
then we jump if there is no carry for do not increment High byte
with that;
brne PC + 2
In the datasheet of Atmega8 it is write
BRNE (branch if not equal) PC <- PC + k + 1 (page 282 on the datasheet i got)
k is 2 => 2+1 = 3, that s mean the next 2 lines will skips !
That mean we go at the "ELSE1_1" not at the "rjmp ENDIF1" and the inc ABS ABS_H deleted...
It true or false ?
Just for the fun...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
First everything looked OK, but after a little playing with maximum values it appears that
the ABS function is not 100% (it's now 99%).
First the definitions in the help file:
Text "Variables"
Integer: A whole number between - 32768 and 32767
Text "ABS"
The ABS function will computes the absolute value of a integer number therefore in the range of -32678 (I believe this must be -32768) to 32768 (and this must be 32767).
So -32768 is a valid value according to the standard.
Executing this line
print ABS(-32768) ; shows -32768 ; should show 32768(but this value is no integer anymore!)
produces the wrong value.
Playing with greater values than 32767 or smaller values then-32768 (by dimension as Long) does not produce an error message but shows random values.
Last edit: Theo 2014-10-30
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Wrong value with ABSfunction:
Is this a typical AVR problem?
Kind Regards
Theo.
ASM File
Did I something wrong by the reporting of this problem?
Theo.
No. We will look asap.
This is a bug that I came across myself a few days back, but hadn't released a fix for yet. The problem was with the negate operator, which is meant to invert the variable and add one, but which wasn't adding one on AVR.
Please try replacing your copy of gcbasic.exe with the one at http://gcbasic.sourceforge.net/temp/gcbasic.exe and hopefully that will fix it. Thanks for letting us know!
compiler Bug !
-127 is translate by FF81
Generated Code asm;
FF81 XOR FFFF = 126 ' error !!!
pat, that code looks ok. The compiler uses Two's complement, which requires inverting and adding. So, if we negate 127, first we invert, which gives 65408 (or 0xFF80), then we add one and that gives 65409, or 0xFF81.
As an example of why that works, suppose that we're adding 200 to -127. The result should be 73. If we add 200 to 65409, that gives 65609, which overflows to 73 (65609 AND 65535 = 73).
(Please do point out anything that looks like a bug, I'd rather explain how something works than have bug hiding in the compiler!)
Last edit: Hugh Considine 2014-10-30
Thanks for your quick answer.
I'll never speak about bug now. ;-)
this is the function ABS in ASM;
In case SYSCALCTEMPA_H bit is 1 , that a negative number
we make a COM function on the 2 bytes and put the result in SYSCALCTEMPA_H and SYSCALCTEMPA_L
then copy on ABS and ABS_H
OK
Then ,we increment ABS and ABS_H for to correct that you explain on the previous post
it is OK
then we jump if there is no carry for do not increment High byte
with that;
In the datasheet of Atmega8 it is write
k is 2 => 2+1 = 3, that s mean the next 2 lines will skips !
That mean we go at the "ELSE1_1" not at the "rjmp ENDIF1" and the inc ABS ABS_H deleted...
It true or false ?
Just for the fun...
The .lst have a F409
I don't find the code in the datasheet.
May be it is correct if the assembler make a (PC+2) like a 1
I Found the "instruction set nomenclature"
1111 01KK KKKk k001 K=1 => F409
F409 mean k=1
the code is OK !
Sorry wrong way, good code...
Last edit: pat 2014-10-30
Hugh, I installed the new gcbasic.exe.
First everything looked OK, but after a little playing with maximum values it appears that
the ABS function is not 100% (it's now 99%).
First the definitions in the help file:
Text "Variables"
Integer: A whole number between - 32768 and 32767
Text "ABS"
The ABS function will computes the absolute value of a integer number therefore in the range of -32678 (I believe this must be -32768) to 32768 (and this must be 32767).
So -32768 is a valid value according to the standard.
Executing this line
produces the wrong value.
Playing with greater values than 32767 or smaller values then-32768 (by dimension as Long) does not produce an error message but shows random values.
Last edit: Theo 2014-10-30
I tested with the last release , i see no code probleme for this, the old i dont know...
The limit of the signed int is - 32768 and 32767
that mean you cannot have +32768 !
the help online is not correct
In fact the limit is -32767 32767
When it's out of limit , why there is no messagee ? (I am agree with you)
But the result , i think is the low part of the long value.
If all the values that is between the limit have a good result,
everything it 's alright, no problem.
Last edit: pat 2014-10-30