[<<] [<] Page 1 of 1 [>] [>>] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
More nocturnal programming problems
From: David Willmore ####@####.#### Date: 15 Mar 2004 10:20:44 +0000 Message-Id: <200403151013.i2FADHs5017304@localhost.localdomain> Hello, again. Same situation as before, sorry. Can anyone enlighten me as to why: msg_len EQU (message_end - message_start) message_start: retlw b'00000000' [... etc ...] retlw b'11111111' message_end: Gives me a: /usr/home/willmore/src/pic/test/10/test.asm:35:Error [116] Value of symbol "message_len" differs on second pass pass 1=0, pass 2=125 Error code : 256 It seems that it's upset that when it first evaluates the expression, it has no values for message_end and message_start, so their difference is 0, but after having a longer look at things, it decides that it's now 125. This causes a bit of confusion and an error. Again, am I missing some common trick or am I expecting the wrong things out of my tools? i.e. pilot error or pilot error. :) Cheers, David | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: More nocturnal programming problems
From: Craig Franklin ####@####.#### Date: 16 Mar 2004 02:07:11 +0000 Message-Id: <1079402794.1454.11.camel@r2d2> On Mon, 2004-03-15 at 04:13, David Willmore wrote: > Hello, again. > > Same situation as before, sorry. > > Can anyone enlighten me as to why: > > msg_len EQU (message_end - message_start) > > message_start: > retlw b'00000000' > [... etc ...] > retlw b'11111111' > message_end: > > Gives me a: > /usr/home/willmore/src/pic/test/10/test.asm:35:Error [116] Value of symbol "message_len" differs on second pass > pass 1=0, pass 2=125 > Error code : 256 > > It seems that it's upset that when it first evaluates the > expression, it has no values for message_end and message_start, > so their difference is 0, but after having a longer look at > things, it decides that it's now 125. This causes a bit of > confusion and an error. > > Again, am I missing some common trick or am I expecting > the wrong things out of my tools? i.e. pilot error or > pilot error. :) > Symbols assigned a value using EQU can't be changed. gpasm checks the value on each pass to make sure they match. On the first pass message_end and message_start have a value of 0. So msg_len has a value of 0. On second pass message_end is 125, so msg_len changes. You can change to the SET directive or use a #define. A few other options exist. Pick the one that suits you best. > Cheers, > David > > --------------------------------------------------------------------- > To unsubscribe, e-mail: ####@####.#### > For additional commands, e-mail: ####@####.#### > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: More nocturnal programming problems
From: "Paul B. Webster" ####@####.#### Date: 17 Mar 2004 11:59:01 +0000 Message-Id: <1079524721.3402.30378.camel@dads.webstermed> On Wed, 2004-03-17 at 13:36, Craig Franklin wrote: > gpasm does allow forward references to symbols, so this isn't always > true. It takes two passes of the source code. Oops! That *is* what two-pass assemblers are about, of course. I am pontificating without, at this point, actually using the thing - in fact, I am woefully out of practice - it shows, doesn't it? OK, it perhaps doesn't matter whether the code block itself is early or late in the program as long as dependent variables (the "EQU" one) follow after all variables upon whose actual value they depend. Pass one generates the symbol table defining the value of all the symbols, which may then be used wherever referenced in pass two. Pass two actually resolves all the symbols again, but only to check them against those already present in the symbol table, giving the error specified if they disagree. > Without seeing all of his source code, it is difficult to know which is > best. As a general approach to string handling, the only matter of concern is whether the "message" is binary or text. Text data is almost universally (FORTH excepted) stored in zero-terminated strings (as I recall, MPASM provides for these,) because you only require a single pointer to represent the string. For binary strings, you require either start and end(+1) pointers, or a pointer to the string which is itself prefixed by a length descriptor (byte or word, depending on the maximum length string to be permitted). There can be few exceptions to the rule that passing a single pointer is more concise than passing two pointers because the code required to load the second pointer for every call is always (much) more expensive than either the terminator (null) word or the length prefix to the corresponding string (especially where the string is used more than once), and within the output subroutine, a test (branch) for zero or iteration counter (DJNZ) is far more efficient than a comparison-for-end procedure. Revisiting the code in question, if "message" is in fact binary and strings limited to less than 256, we should be able to use: message_start: retlw msg_len-1 retlw b'00000000' [... etc ...] retlw b'11111111' message_end: msg_len EQU (message_end - message_start) ... in conjunction with a subroutine that reads the first element into the loop counter. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ My apologies - I had not noticed that this list works in a most annoyingly non-standard fashion, and my reply went to Craig only! On Wed, 2004-03-17 at 13:36, Craig Franklin wrote: On Tue, 2004-03-16 at 06:34, Paul B. Webster wrote: > On Tue, 2004-03-16 at 13:06, Craig Franklin wrote: > > > Symbols assigned a value using EQU can't be changed. > > But really, that's not the most important thing. What is important, > is the concept of the "pass" - that message_start and message_end must > be defined before *anything* that uses them. > > Your code then needs to read: > > message_start: > retlw b'00000000' > [... etc ...] > retlw b'11111111' > message_end: > > msg_len EQU (message_end - message_start) > > ... and by the same token, whatever code uses msg_len, must follow > after all three declarations. > gpasm does allow forward references to symbols, so this isn't always true. It takes two passes of the source code. > In practice, this demands that your message blocks appear after the > initial "start jmp begin" code, and before the subroutines which > reference them. > > Of course, most message print routines use a zero-terminated string > anyway, because the code to detect the zero is vastly more concise than > code which requires two parameters (pointer and length) to call. > > Have I missed something? Without seeing all of his source code, it is difficult to know which is best. -- Cheers, Paul B. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: More nocturnal programming problems
From: David Willmore ####@####.#### Date: 17 Mar 2004 17:09:48 +0000 Message-Id: <200403171700.i2HH0NqX025665@localhost.localdomain> > Paul wrote: > OK, it perhaps doesn't matter whether the code block itself is early > or late in the program as long as dependent variables (the "EQU" one) > follow after all variables upon whose actual value they depend. Pass > one generates the symbol table defining the value of all the symbols, > which may then be used wherever referenced in pass two. > > Pass two actually resolves all the symbols again, but only to check > them against those already present in the symbol table, giving the error > specified if they disagree. This would seem to preclude forward references. If the symbol has no value (is not defined) when it is used, then a later definition will no propogate back? > > Without seeing all of his source code, it is difficult to know which is > > best. It's no secret, it's just no complete and I couldn't see how any more than what was shown was meaningful, sorry. Shall I post it here? It's still not quite complete, so please pardon the mess. :) Basically, before that table, there is a little prolog that goes: data_lookup: movwf PCL_tmp movlw LOW data_table ; load in the low byte of the table data start address addwf PCL_tmp,f movlw HIGH data_table ; load in the high byte of the table data start address btfsc STATUS,C ; skip if carry clear addlw 1 ; stuff in the carry bit movwf PCLATH ; stick it in the high byte PC latch movf PCL_tmp,w ; load in the PCL value movwf PCL ; jump data_table: ; Char 1 'W' retlw b'01111110' retlw b'10000000' retlw b'01111000' ... data_end: You set the index in w and call data_lookup. Yeah, there's probably a cleaner way to do this, but it handles tables up to 256 bytes and they can straddle pages. And, it wouldn't be all too hard to extend it to being able to use all of memory. The site using the EQU just runs a counter from 0 up until the length define value -1. (it's a modulo operation as the message is a scrolling banner that loops forever). > As a general approach to string handling, the only matter of concern > is whether the "message" is binary or text. Text data is almost > universally (FORTH excepted) stored in zero-terminated strings (as I > recall, MPASM provides for these,) because you only require a single > pointer to represent the string. For binary strings, you require either > start and end(+1) pointers, or a pointer to the string which is itself > prefixed by a length descriptor (byte or word, depending on the maximum > length string to be permitted). For really specific strings, I just have a binary string and a programatic constant for the length. Call it 'none of the above'. :) Maybe a pascal string with a displaced length value? > There can be few exceptions to the rule that passing a single pointer > is more concise than passing two pointers because the code required to > load the second pointer for every call is always (much) more expensive > than either the terminator (null) word or the length prefix to the > corresponding string (especially where the string is used more than > once), and within the output subroutine, a test (branch) for zero or > iteration counter (DJNZ) is far more efficient than a comparison-for-end > procedure. What about addressing the buffer with the pointer % the length? :) > Revisiting the code in question, if "message" is in fact binary and > strings limited to less than 256, we should be able to use: > > message_start: > retlw msg_len-1 > retlw b'00000000' > [... etc ...] > retlw b'11111111' > message_end: > > msg_len EQU (message_end - message_start) > > ... in conjunction with a subroutine that reads the first element into > the loop counter. Which precludes using the length as a literal value--now it has to be in a memory location or register. For embeddid (i.e. tiny) processors that can count precious bytes. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > My apologies - I had not noticed that this list works in a most > annoyingly non-standard fashion, and my reply went to Craig only! That's a religious argument for another day! ;) Thanks for the advice. Cheers, David | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: More nocturnal programming problems
From: David Willmore ####@####.#### Date: 18 Mar 2004 22:59:52 +0000 Message-Id: <200403182259.i2IMxA0t030814@localhost.localdomain> > > msg_len EQU (message_end - message_start) > > Symbols assigned a value using EQU can't be changed. gpasm checks the > value on each pass to make sure they match. On the first pass > message_end and message_start have a value of 0. So msg_len has a value > of 0. On second pass message_end is 125, so msg_len changes. > > You can change to the SET directive or use a #define. A few other > options exist. Pick the one that suits you best. VARIABLE msg_len=(message_end - message_start) works perfectly. I tried SET, but it requires the variable to be defined first, so why not put the value in the VARIABLE statement in the first place? I looked at the opcodes produced and they've got the right value in them (sublw msg_len comes out as 0x3C7D and the msg_len is 125 or 0x7D). Thanks, Craig and everyone else. Does the list take attachements? If so, I'll post a version of the code for everyones enjoyment. :) Cheers, David | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[<<] [<] Page 1 of 1 [>] [>>] |