Data storage error in Table command, when data ends in zero byte.

PhilHornby

Senior Member
I routinely use the TABLE area to store data strings intended for display on an LCD. Each string is marked with a trailing zero byte, so that the Display Routine can find each individual message (a habit I picked up in 1979, on the PDP-11 ;) ) .

However, I've recently noticed a slight bug:

If you give a specific TABLE location for the data, it will allow you to overwrite the previous data - if it contains a 0x00h (null) byte.
(If the last byte is anything other than a 0x00h, the 'compiler' protests that the location is already in use).

So for example:-
Rich (BB code):
table 0,("ABC",0)
table 3,(2)       ;incorrectly says location 3 is free 
and stores
Code:
[0]   41,42,43,02,00,00,00,00
[8]   00,00,00,00,00,00,00,00
[16]  00,00,00,00,00,00,00,00
This code
Rich (BB code):
table 0,("ABC",0)
table (2)        ;this works properly (regardless of null)
stores this:-
Code:
[0]   41,42,43,00,02,00,00,00
[8]   00,00,00,00,00,00,00,00
[16]  00,00,00,00,00,00,00,00


This can be demonstrated in the simulator :-

Rich (BB code):
; Program to print Table data.
;
symbol TableLocation = W2
symbol Rows           = b2
symbol Columns       = b3
symbol Width       = 8
symbol Height       = 3

    TableLocation = 0

    sertxd (cr,lf,"Table Data:-")
    for Rows = 1 to Height
        sertxd (cr,lf,"[",#TableLocation,"]",tab)
        for Columns = 1 to Width
            readtable TableLocation,b0
            inc TableLocation
            gosub B0_to_HEX
            if Columns <> Width then
                sertxd (",")
            endif
        next Columns
    next Rows

    stop
 
B0_TO_HEX:
        b1 = b0 / 16 + "0"
        gosub Nybble
        b1 = b0 & 15 + "0"
Nybble:
        if b1 > "9" then : b1 = b1 + 7    endif
        sertxd(b1)
        return
 

Buzby

Senior Member
I'd never noticed before that PE tells you if a TABLE location is already used.

Because you pre-define the table data, it's not something you are likely come across, unless you make a typo.

It could maybe a problem if you had very a very complicated symbol table, where symbol definitions for table addresses depended on #DEFINE directives.
 

Aries

New Member
I had noticed this quite a long time ago - I assumed it was because the only way the compiler knows a location has already been used is that it has a non-zero entry. From (my) memory, I think it applies to DATA as well.
 

hippy

Technical Support
Staff member
I assumed it was because the only way the compiler knows a location has already been used is that it has a non-zero entry. From (my) memory, I think it applies to DATA as well.
That is correct. Any data byte which is a zero is treated as unused so can be overwritten later.
Code:
#Picaxe 20X2
#Terminal 9600

Data      0, ( "0", "1", "2" , "3", 0, "5" )
Data      4, ( "X" ) 

Table     0, ( "0", "1", "2" , "3", 0, "5" )
Table     4, ( "Y" )

Read      4, b0 : SerTxd( "DATA[4]  = ", b0, CR, LF ) 
ReadTable 4, b1 : SerTxd( "TABLE[4] = ", b1, CR, LF )
I don't know if it was intended but it can be useful when one has a long definition and wants some some #IFDEF-ELSE-ENDIF conditional code, #MACRO or #DEFINE to set particular bytes of that data, though there are other ways to do it -
Code:
;               1   2      2
;               67890123   4
Data     16, ( "This is ", 0, 0, 0, 0, "a 20X2", CR, LF )
#IfNDef _20X2
  Data   24, (            "not " )
#EndIf

b0 = 16
Do
   Read b0, b1
   If b1 <> 0 Then : SerTxd(b1) : End If
   b0 = b0 + 1
Loop While b1 <> LF
Change to "#Picaxe 28X2" to see that in action
 

PhilHornby

Senior Member
In my case, I always used to define the storage location, because I needed to know it, in order to access the data. With null-terminated strings, I don't.
(I have routine which takes a message no. as a parameter and searches the table to find it, using the nulls as message delimiters. This trades ease of coding against run-time inefficiency).

The table command does store the trailing null - so why doesn't it count as being "in use"?
 

hippy

Technical Support
Staff member
The table command does store the trailing null - so why doesn't it count as being "in use"?
I would guess the DATA and TABLE arrays are pre-initialised to zero within the compilers and thus 'zero means unused'.

It will have been however it is for a long while so can't see that changing any time soon. This is I think the first time I have ever seen an issue relating to it in all these years.
 
Top