PDA

View Full Version : Is there any easy way to assign a string to a byte?



Oldbitcollector (Jeff)
01-17-2009, 11:35 AM
I know that you can use a DAT statement to assign a string to a byte like this:




DAT

name byte "This is a line of text.",0





But is there an easy way to do something like this?




VAR

BYTE name[20]


PUB

BYTE[@name]:=string("This is a line of text.",0





Thanks!
OBC

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?

Check out: Protoboard Introduction (http://jeffledger.googlepages.com/Protoboard_Introduction.pdf) , Propeller Cookbook 1.4 (http://ucontroller.com/Propeller%20Protoboard%20Designs%20for%20the%20Beg inner.pdf) & Software Index (http://forums.parallax.com/showthread.php?p=770318)
Updates to the Cookbook are now posted to: Propeller.warrantyvoid.us (http://propeller.warrantyvoid.us)
Got an SD card connected? - PropDOS (http://www.orrtech.net/propdos/)

BradC
01-17-2009, 12:56 PM
Will this work for you ?




X := String("Fred was ere")
repeat i from 0 to strsize(X)+1
byte[ @name ][ i ] := byte[ X ][ i ]



Remember all String("") does is return a pointer to the null terminated string in memory

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cardinal Fang! Fetch the comfy chair.

Mike Green
01-17-2009, 12:57 PM
Use BYTEMOVE. For the byte count, use the length of the string + 1 (to account for the zero byte which is implied at the end).

Like: BYTEMOVE(@name,string("This is a line of text."),24)

StefanL38
01-17-2009, 04:03 PM
Hello OBC,

from the words chosen in your headline I assume there might be a misunderstanding about bytes and strings.

a byte can carry values between 0 and 255. This space can carry ONLY ONE character.
So all a byte can be assigned is a SINGLE character NOT a complete string (of more than one character)


A codeline like this




DAT
name byte "ABC this is a text",0




means
hello compiler do the following:
store in HUB-RAM a byte-SEQUENCE containing the following values: decimal 65,66,67,32,116,104

where 65 is ASCII-Code for "A"
where 66 is ASCII-Code for "B"
where 67 is ASCII-Code for "C"
where 32 is ASCII-Code for " "
where 116 is ASCII-Code for "t"
where 104 is ASCII-Code for "h"
where 105 is ASCII-Code for "i"
where 115 is ASCII-Code for "s"

etc.
last byteVALUE in this sequence zero (to terminate the string

the HUB-RAM-adress can be referenced by the label "name"

so the word "byte" says the compiler store the values that are following the word "byte" as bytes=8bit-values and NOT as words=16bit-values and NOT as longs=32bit-values

the basic use for DAT is




DAT
name byte 65,66,67,32,116,104,......,0





Here it is clear that integerNUMBERS are used and by using "byte" the compiler knows 8bitvalues are following.

Now the compiler offers a variation to storing byte-SEQUENCES for strings
that is much better readable than 65,66,67,32,116,104,......,0




DAT
name byte "ABC this is a text",0




I'm NOT sure if the construction Brad suggested will work. Somewhere in the memory the bytesequence "Fred was here" has to be stored
But there is nothing said about WHERE it should be stored. To know it REAL I / you would have to make a test-program
maybe the compiler is clever enough that you can use variable "X" as reference-label AND the compiler reserves HUB-RAM-space
for the bytesequence "Fred was here",0


So there is no way to do something like in delphi or VB
like variableB := variableA for strings


know I have a question about bytemove

Does the command bytemove in SPIN work the same way as in other programming-languages ?
I mean does it copy a bytesequence from source to destination regardless of what the destination and source-adress is ?
f.e.




DAT
MyStr byte 0,0,0,0,0
Voltage long 0
Current long 0
MaxTemp long 1000




reserves 5 bytes of HUB-RAM




bytemove(@MyStr,string("12345667890",0)




Will this bytemove-command write ELEVEN bytes starting at adress of MyStr overwriting the values of the DAT-variables Voltage, Current, MaxTemp ?

best regards

Stefan

Post Edited (StefanL38) : 1/17/2009 8:15:24 AM GMT

BradC
01-17-2009, 04:30 PM
StefanL38 said...

I'm NOT sure if the construction Brad suggested will work. Somewhere in the memory the bytesequence "Fred was here" has to be stored
But there is nothing said about WHERE it should be stored. To know it REAL I / you would have to make a test-program
maybe the compiler is clever enough that you can use variable "X" as reference-label AND the compiler reserves HUB-RAM-space
for the bytesequence "Fred was here",0



Hrm.. well I *am* sure.

When you use STRING("XX") it compiles the null terminated string into the bytecode for that spin method. What is returned is an address pointer to that string.

If you would like to verify that yourself, why not use one of the after-market compilers to inspect the bytecode disassembly listing and see how it works.

Mikes suggestion does precisely the same thing, but as usual, in a smaller, faster and more code-efficient fashion :)


StefanL38 said...


Does the command bytemove in SPIN work the same way as in other programming-languages ?
I mean does it copy a bytesequence from source to destination regardless of what the destination and source-adress is ?
f.e.




DAT
MyStr byte 0,0,0,0,0
Voltage long 0
Current long 0
MaxTemp long 1000









bytemove(@MyStr,string("12345667890",0)




This won't work as you have not told bytemove how many bytes to copy. In addition STRING("") null terminates for you, so you can leave out the ",0" at the end.

In any case, if you changed it to ...




bytemove(@MyStr,String("12345667890"),12)




.. it would do what you were originally suggesting, and yes it will quite happily trample over "Voltage" and "Current" also

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cardinal Fang! Fetch the comfy chair.

StefanL38
01-18-2009, 03:33 AM
Hello Brad,

thanks for clearing things up and the correction about the parameter telling how many bytes to move

best regards

Stefan

Beau Schwabe
01-18-2009, 07:59 AM
Doesn't the STRING qualifier already format everything into a BYTE string that you can read or write to without having to use BYTEMOVE?




TestString := string("Hello")

BYTE[TestString][0] := 89 'Replace 'H' with 'Y'
BYTE[TestString][5] := 119 'add a 'w' to the end of 'Hello'
BYTE[TestString][6] := 0 'terminate string with a Zero

gr.text(0,82,TestString) ' this will print the word 'Yellow'


▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 1/18/2009 1:52:10 AM GMT

BradC
01-18-2009, 08:21 AM
Beau Schwabe (Parallax) said...
Doesn't the STRING qualifier already format everything into a BYTE string that you can read or write to without having to use BYTEMOVE?



Yeah, it does. I assumed from the snippet that OBC posted he wanted a way of assigning that to another byte array defined elsewhere, thus the need for the copy.

<edit> I did not see the "read or write to" in the above paragraph. Yes you can read from it, but as it is compiled into the spin method it is referenced from, if you write to it and get it wrong you can easily cause mayhem and destruction. Be careful with that!

If you looked at a spin object.. you get something like this

Header/Method Table
DAT Section
PUB Method 1
PUB Method 1 string definitions
PUB Method 2
PRI Method 1
PRI Method 1 string definitions
End

So each spin method that has STRING("") defs in it has them compiled in starting immediately after the final return() in the method. If you were to overwrite a string with a longer string you would quite probably bulldoze either into the next string() or over the bytecode of the next method. Either way, things won't turn out the way you want them to.
On the other hand, if you were to define a Method like this




DAT
bytecode 0,1,2,3,4,5,6,7,8
bytecode_end

PUB MethA
return String(1)
PUB MethB
return String(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
PUB MethC
bytemove(MethA+2,@bytecode,@bytecode_end-@bytecode)





You now have an efficient method for changing the runtime code in "MethB" on the fly.
The address preceding the end of the value returned by MethA + 2 should be the start of MethB. You can just copy arbitrary bytecode in there and execute it with a call to MethB. Just make sure you end the bytecode with an explicit return/abort as you will trample the pre-compiled bytecode.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cardinal Fang! Fetch the comfy chair.

Post Edited (BradC) : 1/18/2009 1:46:40 AM GMT

Oldbitcollector (Jeff)
01-18-2009, 09:00 AM
Wow.. I'm glad I asked..

Several good methods presented for handling the problem.

Thank you gentlemen!

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?

Check out: Protoboard Introduction (http://jeffledger.googlepages.com/Protoboard_Introduction.pdf) , Propeller Cookbook 1.4 (http://ucontroller.com/Propeller%20Protoboard%20Designs%20for%20the%20Beg inner.pdf) & Software Index (http://forums.parallax.com/showthread.php?p=770318)
Updates to the Cookbook are now posted to: Propeller.warrantyvoid.us (http://propeller.warrantyvoid.us)
Got an SD card connected? - PropDOS (http://www.orrtech.net/propdos/)

softex
02-01-2009, 02:01 AM
Boy, if even OBC is struggling somewhat with this then perhaps someone needs to create a good string handling object for the prop. I know I sure could use it. And esp. when it comes to converting a string like "123" into a decimal value. BTW after grappling with this stuff in PROTON BASIC (like PICBASIC) for a couple of years, they like to refer to a defined zero-terminated string as a byte ARRAY which, of course, is what it is.

-Dave

Phil Pilgrim (PhiPi)
02-01-2009, 05:33 AM
What would be nice is for Spin to recognize three kinds of string constructors and, in the process, deprecate string(). This would be replaced with:

····str0() for zero-terminated strings,
····nstr() for strings (limited to 255 characters) with a length byte in position 0, and
····str() and/or byte() for generic strings (simple byte arrays) with no length indicator.

Zero-terminated strings can be a real nuisance in data transmission, for example, when you want to send a zero-valued byte, such as CLS. In such a case, you have to terminate the string, send the zero as a single character, then resume with another string. It's either that or define non-zero cognates for zero which, in itself, can lead to awkward situations.

The above forms could easily be imitated for constructing inline word() and long() arrays, too, rather than having to declare them in a VAR or DAT section. There's also no reason that the elements of such arrays have to be constants, either. A statement of the form




addr := byte("ABC", my_variable, "DEF")




could easily be compiled to produce the bytecode equivalent of




addr := byte("ABC", 0, "DEF")
byte[addr + 3] := my_variable




This would make possible the construction of variable-length parameter lists in method calls, viz:




value := polynomial(nlong(x, a, b, c, d))




By reading the long at the address passed, the method would know that there are five additional arguments: the independent variable and four coefficients, from which it could compute the result:

····ax3 +bx2 +cx + d

All of these things can be accomplished without any changes to the Spin interpreter; only to the compiler.

-Phil

Oldbitcollector (Jeff)
02-01-2009, 05:47 AM
Right on! These would be nice additions.

I guess one of the reasons that I've had so much trouble here is that I have
no frame of reference to compare some of these things making them harder to absorb.
For instance the fact that I've learned various dialects of BASIC did more to hinder
my adapting to this than anything... You simply cannot directly compare directly to string$. :)

BTW, OBC does NOT claim to be an expert in EE or the Propeller for that matter.
After two years I'm reasonable strong in many areas, but there are some holes I'm still
working on guys. :)

OBC

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?

Check out: Protoboard Introduction (http://jeffledger.googlepages.com/Protoboard_Introduction.pdf) , Propeller Cookbook 1.4 (http://ucontroller.com/Propeller%20Protoboard%20Designs%20for%20the%20Beg inner.pdf) & Software Index (http://forums.parallax.com/showthread.php?p=770318)
Updates to the Cookbook are now posted to: Propeller.warrantyvoid.us (http://propeller.warrantyvoid.us)
Got an SD card connected? - PropDOS (http://www.orrtech.net/propdos/)

w8an
12-07-2009, 08:57 AM
Just came across this thread... Excellent ideas, PhiPi