View previous topic :: View next topic |
Author |
Message |
dw
Joined: 22 Feb 2005 Posts: 15
|
Posted: Mon Feb 28, 2005 4:49 pm Post subject: different behaviour Local / Dim |
|
|
Code: | Sub Lcdfill(byref Strlcd As String * 16)
Local Strlen As Byte ' with dim its ok
Print "<" ; Strlcd ; ">" 'here passed string is ok
Strlen = Len(strlcd)
Print "<" ; Strlcd ; ">"'here it is different
Strlen = 16 - Strlen
If Strlen < 0 Then Strlen = 0
Strlcd = Strlcd + Space(strlen)
End Sub |
Just as an example: this code fills up string to 16 character with spaces
if strlen is defined as global var everthing is ok
If it is local the 12th character is changed after the LEN function
i got other problems on other sub.
The behaviour is always different. So dont´t waste time to think about the change of the char.
But has someone an idea why local var produces unexpected code?
if i seperate this function in a new projekt it works fine.
Stacks are 64,32,64 on Mega32
could it be a stack problem?
Thanks for help.
dw |
|
Back to top |
|
|
oe9vfj
Joined: 17 Jun 2004 Posts: 269 Location: Austria, Hard
|
Posted: Tue Mar 01, 2005 11:45 am Post subject: |
|
|
Your question about stack problem can not be answered with this single SUB in your mail. The Stack-size depends on all components of your application. But it seems to be a stack problem.
I tested your fragment and it worked well.
Please check the statement $DBG in the Help-File.
With this tool you can check the real needed stack sizes. _________________ regards Josef
DOS - File System for BASCOM-AVR on http://members.aon.at/voegel |
|
Back to top |
|
|
dw
Joined: 22 Feb 2005 Posts: 15
|
Posted: Tue Mar 01, 2005 3:55 pm Post subject: |
|
|
Thanks for reply.
Think I ask the wrong question:
I assume that it is a stack problem, but 64,32,64 seems to be ok in my opinion. The sub are not nested that much.
Maybe some other has had the same problem, and the solution was not more stack size.
So there are no known bugs regarding local varibles?
Thanks a lot,
dw |
|
Back to top |
|
|
oe9vfj
Joined: 17 Jun 2004 Posts: 269 Location: Austria, Hard
|
Posted: Tue Mar 01, 2005 4:11 pm Post subject: |
|
|
I use Sub and Function very often in my program and if problems occurs, the reason was to low stack sizes.
Passing variables byVal will eat up a lof of frame size, especially passing strings with this way.
The Print Statement also use the Frame space (16 Bytes are reserved for it). Normal conversions of numbers have no problem, because they need less than 16 Bytes (except DOUBLE, but if you print DOUBLE, the compiler reserves 24 Bytes for this conversion space).
Other implicit function in Print-Statement, which result in a string, have to be checked for the length of the produced string.
For example:
Print Lookup(value, Label)
may not produce a string longer than 16 Bytes, otherwise regulary frame-space will be overwritten. This restriction is valid for all functions within a Print statement, which produces a String.
I hope, I could get you some hints to check your problem?
Did you checked stack usage with the $DBG option? _________________ regards Josef
DOS - File System for BASCOM-AVR on http://members.aon.at/voegel |
|
Back to top |
|
|
dw
Joined: 22 Feb 2005 Posts: 15
|
Posted: Wed Mar 02, 2005 11:11 am Post subject: |
|
|
Sure,
HW,SW,FR = 41,20,36
so 64,32,64 should be enought.
mmh, must do some more test, maybe i´ve had mor prints for debug in the code.
thnks for help. |
|
Back to top |
|
|
dw
Joined: 22 Feb 2005 Posts: 15
|
Posted: Wed Mar 02, 2005 12:30 pm Post subject: |
|
|
Ok,
i´ve done the StackCheck with local and global var.
i got the same values for HW,SW and FS.
the 12th char is still corrupted using strlen as a local var.
suspicious:
on the stackanalyser the FS goes up from 9 to 36 on the first appearance of the LCDfill sub (without any prints and the string is passed by reference)
Code: | Sub Lcdfill(byref Strlcd As String * 16)
Local Strlen As Byte
Strlen = Len(strlcd)
Strlen = 16 - Strlen
If Strlen < 0 Then Strlen = 0
Strlcd = Strlcd + Space(strlen)
Dbg
End Sub |
|
|
Back to top |
|
|
oe9vfj
Joined: 17 Jun 2004 Posts: 269 Location: Austria, Hard
|
Posted: Wed Mar 02, 2005 1:54 pm Post subject: |
|
|
That's very strange. Can you provide as much code as necessary to reproduce the error. _________________ regards Josef
DOS - File System for BASCOM-AVR on http://members.aon.at/voegel |
|
Back to top |
|
|
philm
Joined: 14 Jul 2004 Posts: 138 Location: Australia
|
Posted: Wed Mar 02, 2005 11:33 pm Post subject: |
|
|
DW,
There may be a problem depending on how much ram space you reserve for your original string that is passed to your lcdfill sub.
If you dim a string of 10 characters, then pass it to lcdfill, it will append another 6 charactres to the original string, because you pass "byref".
There should also be a warning in the compiler report about this.
I am suprised that bascom does not generate a syntax error for "Strlcd As String * 16". In fact it does not matter how long the string is.
Another thing is when strlen = 0 does "Space(strlen)" return zero spaces or 255 spaces?
What happens when "Strlen = 16 - Strlen " and strlen is >16?
If the goal is to fill the rest of the lcd line with spaces, then this can be done by "lcd Space(strlen)" rather than appending strings.
Phil |
|
Back to top |
|
|
dw
Joined: 22 Feb 2005 Posts: 15
|
Posted: Thu Mar 03, 2005 11:47 am Post subject: |
|
|
philm wrote: |
I am suprised that bascom does not generate a syntax error for "Strlcd As String * 16". In fact it does not matter how long the string is.
|
your right, *16 makes no sense when passing by ref. its dirt from testing with passing by val. But that did also not work
Quote: | Another thing is when strlen = 0 does "Space(strlen)" return zero spaces or 255 spaces? |
that seem to work with a 16 char string i got no problems, but with shorter ones the 12th is corrupted
Quote: | What happens when "Strlen = 16 - Strlen " and strlen is >16? |
yes, i also think that could be a problem
but changing the code to:
Code: | Sub Lcdfill(byref Strlcd As String) ' without *16
Local Strlen As Integer ' integer NOW
Strlen = Len(strlcd)
Strlen = 16 - Strlen
If Strlen > 0 Then Strlcd = Strlcd + Space(strlen)
End Sub |
causes the same behaviour.
I do not belive that the SUB itself is the problem, i have other problem on other function with local vars e.g local var is never changed.
there seems to be a general mistake in code
BTW: Report file says that :
--------------------------------------------------------------------------------
Warnings:
--------------------------------------------------------------------------------
HWSTACK not used
SWSTACK not used
FRAME not used
ADCD not used
Source string could be too big to fit into target string in line 346
...
Source string could be too big to fit into target string in line 754
Who on hell defined HWSTACK , SWSTACK and FRAME? And what is it for?
What about the String warnings?
Thanks a lot for your help. |
|
Back to top |
|
|
oe9vfj
Joined: 17 Jun 2004 Posts: 269 Location: Austria, Hard
|
Posted: Thu Mar 03, 2005 2:47 pm Post subject: |
|
|
Hi,
For Print and LCD is SPC(x) better than SPACE(x).
SPACE(x) uses a temporary String-variable. SPC(x) sends the Spaces 'on the fly' to the UART or LCD.
HWSTACK (hard ware Stack) SWSTACK (Soft Stack) and FRAME (Frame Size) are defined in the Option/compiler/chip setting and is normally not used by the application code.
The Line:
Source string could be too big to fit into target string in line 346
is a hint for you to check that line, whether there can be a problem with a string length. _________________ regards Josef
DOS - File System for BASCOM-AVR on http://members.aon.at/voegel |
|
Back to top |
|
|
dw
Joined: 22 Feb 2005 Posts: 15
|
Posted: Thu Mar 03, 2005 3:28 pm Post subject: |
|
|
I´ve generated two different assambler files with local var an without it.
They differ not that much. I´ve inserted some nops to get on the same adress for all other subs so a Diff will show the diffence between the assembler code of that little tricky sub.
I´ve not seen any suspicious, but i do not the know atmel memnonic very well.
Someone there who is fit in (win)diff and assembler and who would like to give a try?
It´s just about 30 lines.
Where to post it? |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Thu Mar 03, 2005 9:30 pm Post subject: |
|
|
Hi,
Try this code.
Best regards,
Luciano
Code: |
'--------------------------------------------------------------
'BASCOM-AVR IDE Version : 1.11.7.7
'Compiler: Version 1.11.7.7
'Serial : Serial DEMO
'
'Author: Luciano
'Purpose: Forum post reply, to be run with the BASCOM AVR Simulator.
'
'HW Stack: 32 (Default value)
'Soft Stack: 8 (Default value)
'Framesize: 16 (Default value)
'Processor: Mega32
'
'Note about DECLARE SUB:
'If BYREF or BYVAL is not provided the parameter is passed by reference.
'--------------------------------------------------------------
Dim Strlcd As String * 16
Declare Sub Lcdfill(string_in As String)
'Uncomment the various test cases
'Strlcd = "1"
Strlcd = "123456789012345"
'Strlcd = "1234567890123456"
'Strlcd = ""
'Strlcd = " "
'Strlcd = " "
'Strlcd = " "
Call Lcdfill(strlcd)
Print "Back to main program!"
Print "<" ; Strlcd ; ">"
End
Sub Lcdfill(string_in As String)
Local String_in_len As Byte
Local String_in_padding As Byte
Print "<" ; String_in ; ">"
String_in_len = Len(string_in)
Print "<" ; String_in ; ">"
If String_in_len < 16 Then
String_in_padding = 16 - String_in_len
String_in = String_in + Space(string_in_padding)
End If
Print "<" ; String_in ; ">"
End Sub
|
4.3.2005
I have edited my post and added Print "Back to main program!" and Print "<" ; Strlcd ; ">" to see
that the string passed by reference has been modified by the called sub. |
|
Back to top |
|
|
dw
Joined: 22 Feb 2005 Posts: 15
|
Posted: Fri Mar 04, 2005 11:44 am Post subject: |
|
|
That code worked fine.
And, mea culpa i know why.
It is a good ideal to reserve enought mem for the string.
instead of is the goal.
I´ve looked a thousend times on that, but never saw the missting 1.
So, sorry for wasting your time finding that little stupid error.
|
|
Back to top |
|
|
|