News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Copy String array to another String array odd behaviour

Started by trastikata, Aug 20, 2021, 05:22 PM

Previous topic - Next topic

trastikata

Hello all,

because of limited RAM in a complex program, I am repurposing a String as a Byte array in the same time. I found an odd behaviour when copying one String to another String if the String being copied contains an array of bytes containing 0.
Dim sBuffer1 As String * 64
Dim sBuffer2 As String * 64
sBuffer1 = "TEST" + 0 + "TEST1" + 0 + "TEST3"

I know that strings are 0-terminated so when I copy a String (used as byte array) to another String I'd expect as possibility that the bytes will be copied only until the first 0 in the array.

'Doesn't copy the entire array
sBuffer2 = sBuffer1

What I found odd is that copying each individual byte in the array doesn't work as expected i.e. copying all bytes, but doing a loop would work?

  'Doesn't copy the entire array
  sBuffer2[0] = sBuffer1[0]
  sBuffer2[1] = sBuffer1[1]
  '....
  sBuffer2[63] = sBuffer1[63]
 
  'Will copy all
  For i = 0 To 63
    sBuffer2[i] = sBuffer1[i]
  Next

top204

It is not an odd behaviour, it is how a String variable works, as opposed to a Byte array. :-) It's the same mechanism used by many languages in the past and some good ones in the present, and used for String variables since String variables were created back in the late 1970s. However, a lot of "bloated" computer languages make String variables a lot more complicated and have lengths and types and addresses etc at the beginning of the String's RAM, because they are not true String types, they are objects that immitate a String variable from an array or List of structures (extremely inefficient, but still handy to use), and one of the reasons I always state "Object Oriented languages actually waste a lot of space and time", but are seen as more efficient for some inexplicabe reason! Maybe more efficient to share code around, but certainly not more efficient where it truly matters. i.e. The computer or microcontroller!

You cannot use a 0 value in the middle of a String variable, otherwise, that is the Null, and the String will terminate at that position as far as the compiler's functions and commands are concerned.

For example:
sBuffer1 = "TEST" + 0 + "TEST1" + 0 + "TEST3"

The sBuffer1 String now, officially, only holds "TEST", because the 0 after it has terminated it.

So the line: sBuffer2 = sBuffer1, is doing as it should with a String variable and copying one string into another until the Null terminator is located. Look at the assembler code for that line by pressing the F2 button:

F1_000026 equ $ ; in [TEST_18F25K20.BAS] sBuffer2 = sBuffer1
    lfsr 0,sBuffer2
    lfsr 1,sBuffer1
    movlw 64
_pblb__2
    movf INDF1,F,0
    bz _pblb__3
    movff POSTINC1,POSTINC0
    decfsz WREG,F,0
    bra _pblb__2
_pblb__3
    clrf INDF0,0

The mnemonic "bz _pblb__3" exits the loop when "movf INDF1,F,0" has found the 0 (Null) terminator.

To use any value, it must be an array, because they do not have terminators.

To use the same RAM as the String variables for Byte array variables, you can use:

Dim bBuffer1[64] As Byte At sBuffer1
Dim bBuffer2[64] As Byte At sBuffer2


If you press the F2 button, you will see in the assembler code that the bBuffer1 and bBuffer2 arrays are using the same RAM locations as sBuffer1 and sBuffer2, and the assembler code has a section text to show they are addressed variables: "; ADDRESSED VARIABLES"

Then the line: bBuffer2 = bBuffer1 produces the, very efficient, assembler code:

F1_000029 equ $ ; in [TEST_18F25K20.BAS] bBuffer2 = bBuffer1
    lfsr 0,105
    lfsr 1,bBuffer1
    movlw 64
_pblb__2
    movff POSTINC1,POSTINC0
    decfsz WREG,F,0
    bra _pblb__2

And as can be seen, there is no terminator comparison, it simply, indirectly, copies one array into the other based upon the length of the source array.

I really, really need to find some time to write my book on the Positron compilers and give some examples of what can and can't be done and an explanation of how they work and why they will not work. :-) But finding the time and money to do so is out of my control at the moment.

trastikata

Quote from: top204 on Aug 21, 2021, 09:11 AMIt is not an odd behaviour, it is how a String variable works....

Les, I really appreciate you taking the time to explain the inner workings of the compiler, it makes programming with Positron much simpler and more efficient.