Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.acorn.programmer > #1905 > unrolled thread

Assembler Help.

Started byGazza <usenet@garethlock.com>
First post2012-07-10 07:09 -0700
Last post2012-07-11 09:26 +0100
Articles 20 on this page of 63 — 18 participants

Back to article view | Back to comp.sys.acorn.programmer


Contents

  Assembler Help. Gazza <usenet@garethlock.com> - 2012-07-10 07:09 -0700
    Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-07-10 08:46 -0700
      Re: Assembler Help. Chris Johnson <chrisjohnson+news@spamcop.net> - 2012-07-10 18:06 +0100
        Re: Assembler Help. jgharston <jgh@arcade.demon.co.uk> - 2012-07-11 11:26 -0700
          Re: Assembler Help. cferris@freeRemoveuk.com.invalid - 2012-07-11 20:05 +0100
            Re: Assembler Help. jgharston <jgh@arcade.demon.co.uk> - 2012-07-11 15:16 -0700
            Re: Assembler Help. Steve Drain <steve@kappa.me.uk> - 2012-07-12 10:25 +0100
              Re: Assembler Help. cferris@freeRemoveuk.com.invalid - 2012-07-13 09:23 +0100
                Re: Assembler Help. Steve Drain <steve@kappa.me.uk> - 2012-07-13 11:16 +0100
                  Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-07-24 05:17 -0700
                    Re: Assembler Help. Gavin Wraith <gavin@wra1th.plus.com> - 2012-07-24 14:02 +0100
                      Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-07-24 06:49 -0700
                    Re: Assembler Help. Steve Drain <steve@kappa.me.uk> - 2012-07-24 15:03 +0100
                      Re: Assembler Help. usenet@garethlock.com - 2012-07-24 08:21 -0700
                        Re: Assembler Help. Steve Drain <steve@kappa.me.uk> - 2012-07-24 17:55 +0100
                          Re: Assembler Help. Theo Markettos <theom+news@chiark.greenend.org.uk> - 2012-08-03 20:26 +0100
                            Re: Assembler Help. cferris@freeRemoveuk.com.invalid - 2012-08-05 08:51 +0100
                    Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-07-24 20:04 +0100
                      Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-07-24 14:16 -0700
                        Re: Assembler Help. Jeremy Nicoll - news posts <jn.nntp.scrap007@wingsandbeaks.org.uk> - 2012-07-24 22:34 +0100
                          Re: Assembler Help. Chris Johnson <chrisjohnson+news@spamcop.net> - 2012-07-24 23:56 +0100
                        Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-07-25 01:42 +0100
                          Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-03 05:54 -0700
                            Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-08-03 17:52 +0100
                              Re: Assembler Help. "Barry Allen (news)" <evanallen@onetel.net.uk.invalid> - 2012-08-04 10:21 +0100
                              Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-04 15:57 -0700
                                Re: Assembler Help. cferris@freeRemoveuk.com.invalid - 2012-08-05 08:48 +0100
                                  Re: Assembler Help. Martin <News03@avisoft.f9.co.uk> - 2012-08-06 10:00 +0100
                                  Re: Assembler Help. Theo Markettos <theom+news@chiark.greenend.org.uk> - 2012-08-06 13:26 +0100
                                    Re: Assembler Help. Martin <News03@avisoft.f9.co.uk> - 2012-08-06 23:13 +0100
                                      Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-07 08:50 -0700
                                        Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-07 15:43 -0700
                                          Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-08-08 00:52 +0100
                                            Re: Assembler Help. usenet@garethlock.com - 2012-08-08 02:03 -0700
                                              Re: Assembler Help. jeffrey.a.doggett@gmail.com - 2012-08-08 02:19 -0700
                                              Re: Assembler Help. druck <news@druck.org.uk> - 2012-08-12 09:05 +0100
                                            Re: Assembler Help. Frank de Bruijn <zuiderduin@hotmail.com> - 2012-08-08 11:40 +0200
                                              Re: Assembler Help. Jeremy Nicoll - news posts <jn.nntp.scrap007@wingsandbeaks.org.uk> - 2012-08-08 11:34 +0100
                                                Re: Assembler Help. Justin Fletcher <gerph@gerph.org> - 2012-08-09 21:19 +0100
                                                Re: Assembler Help. druck <news@druck.org.uk> - 2012-08-12 09:08 +0100
                                                  Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-14 05:17 -0700
                                                    Re: Assembler Help. Chris Johnson <chrisjohnson+news@spamcop.net> - 2012-08-14 14:50 +0100
                                                      Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-08-14 15:03 +0100
                                                    Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-08-14 14:59 +0100
                                                      Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-15 17:01 -0700
                                                        Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-21 03:54 -0700
                                                          Re: Assembler Help. Martin <News03@avisoft.f9.co.uk> - 2012-08-21 12:27 +0100
                                                            Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-21 05:08 -0700
                                                              Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-21 05:25 -0700
                                                                Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-21 08:23 -0700
                                                          Re: Assembler Help. druck <news@druck.org.uk> - 2012-08-21 18:19 +0100
                                                            Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-21 14:20 -0700
                                                              Re: Assembler Help. cferris@freeRemoveuk.com.invalid - 2012-08-22 09:07 +0100
                                                                Re: Assembler Help. Gazza <usenet@garethlock.com> - 2012-08-22 05:28 -0700
                                                                  Re: Assembler Help. Steve Fryatt <news@stevefryatt.org.uk> - 2012-08-22 14:47 +0100
                                                              Re: Assembler Help. druck <news@druck.org.uk> - 2012-08-22 23:11 +0100
                                                                Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-08-29 18:36 +0100
                                                          Re: Assembler Help. Jeremy Nicoll - news posts <jn.nntp.scrap007@wingsandbeaks.org.uk> - 2012-08-22 09:38 +0100
                                            Re: Assembler Help. jgh@arcade.demon.co.uk (Jonathan Graham Harston) - 2012-08-08 23:15 +0100
                                              Re: Assembler Help. Martin Bazley <martin.bazley@blueyonder.co.uk> - 2012-08-09 13:59 +0100
                                                Re: Assembler Help. Steve Drain <steve@kappa.me.uk> - 2012-08-10 15:50 +0100
    Re: Assembler Help. Frank de Bruijn <zuiderduin@hotmail.com> - 2012-07-11 08:30 +0200
      Re: Assembler Help. cferris@freeRemoveuk.com.invalid - 2012-07-11 09:26 +0100

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#2080

FromGazza <usenet@garethlock.com>
Date2012-08-14 05:17 -0700
Message-ID<05efb2a0-cb28-44c1-a80b-f9d9d2e339db@s2g2000vbj.googlegroups.com>
In reply to#2068
Been messing around with ADR and pointers recently to get this LibASH
(asm) to assemble. If the following is doing what I think it does,
then what I have should work...


.sometext : EQUS "This is a test message."+CHR$(0):ALIGN
.tmpstr255 : EQUS STRING$(255,CHR$(0)):ALIGN

...

Loads of code goes here...

...

.sometxtptr : EQUD sometext
.tmpstr255ptr : EQUD tmpstr255

.routine : ADR Rx,sometextptr
           ADR Ry,tmpstr255ptr

...

So at this point Rx should point to address specified by sometext and
Ry should point to tmpstr255. Particularly important about the
tmpstr255, as I use this sort of initially empty string to strcpy
into, so I'm writing to this location. I'm using this sort of thing
all over the place to build strings before display. Copying the
message parts to somewhere I can append to the end without overwriting
code or data.

The latest listing is at http://www.garethlock.com/mem.txt

Confirmation would be appreciated...

[toc] | [prev] | [next] | [standalone]


#2081

FromChris Johnson <chrisjohnson+news@spamcop.net>
Date2012-08-14 14:50 +0100
Message-ID<52bf23a2bcchrisjohnson+news@spamcop.net>
In reply to#2080
In article
<05efb2a0-cb28-44c1-a80b-f9d9d2e339db@s2g2000vbj.googlegroups.com>,
   Gazza <usenet@garethlock.com> wrote:


> .sometext : EQUS "This is a test message."+CHR$(0):ALIGN
> .tmpstr255 : EQUS STRING$(255,CHR$(0)):ALIGN


> .sometxtptr : EQUD sometext
> .tmpstr255ptr : EQUD tmpstr255

This is redundant

> .routine : ADR Rx,sometextptr
>            ADR Ry,tmpstr255ptr

The registers are pointing to the label locations, not the contents.

You simply need

 .routine : ADR Rx,sometext
            ADR Ry,tmpstr255

-- 
Chris Johnson

[toc] | [prev] | [next] | [standalone]


#2082

FromMartin Bazley <martin.bazley@blueyonder.co.uk>
Date2012-08-14 15:03 +0100
Message-ID<a5d824bf52.martin@blueyonder.co.uk>
In reply to#2081
The following bytes were arranged on 14 Aug 2012 by Chris Johnson :

> You simply need
>
>  .routine : ADR Rx,sometext
>             ADR Ry,tmpstr255

His problem is that he's trying to access very distant memory in this
manner, causing 'Bad immediate constant' errors.

I explained the difference between LDR and ADR to his face last year,
shortly after he had posted a very similar query on csap, and I'm more
than miffed that the information apparently still hasn't sunken in.

-- 
  __<^>__   Red sky in the morning: Shepherd's warning
 / _   _ \  Red sky at night: Shepherd's delight
( ( |_| ) ) Mince and potatoes: Shepherd's pie
 \_>   <_/  ======================= Martin Bazley ==========================

[toc] | [prev] | [next] | [standalone]


#2083

FromMartin Bazley <martin.bazley@blueyonder.co.uk>
Date2012-08-14 14:59 +0100
Message-ID<bb7b24bf52.martin@blueyonder.co.uk>
In reply to#2080
The following bytes were arranged on 14 Aug 2012 by Gazza :

> .sometxtptr : EQUD sometext
> .tmpstr255ptr : EQUD tmpstr255
>
> .routine : ADR Rx,sometextptr
>            ADR Ry,tmpstr255ptr
>
> ...
>
> So at this point Rx should point to address specified by sometext and
> Ry should point to tmpstr255.

They don't.  They point to the addresses specified by sometextptr and
tmpstr255ptr.  To make them point to the data contained in those
addresses (i.e. sometext and tmpstr255), you should be using LDR
instead.

ADR, by the way, isn't a real instruction, it's just a convenient
shorthand for assembler programmers.  "ADR Rx,address" assembles to the
machine code for "ADD Rx,PC,(address-PC)" (or SUB, as appropriate),
whatever the difference between address of the data and the address of
the instruction happens to be at the point of assembly.  It doesn't
*load* anything, and it has the same range limitations which affect the
second operand of any instruction - which is why you're using
sometextptr and tmpstr255ptr in the first place, to get around these
limitations.  By storing your destination in memory in this way and
using LDR *instead* of ADR (not using ADR all over again!), you free
yourself from the ARM's limits on immediate constants.

I believe we have had this particular conversation before.  Many times,
in fact. I have particularly vivid memories of the time you accosted me
at last year's London show and demanded that we had this conversation
right now.

-- 
  __<^>__
 / _   _ \         You always find something in the last place you look.
( ( |_| ) )
 \_>   <_/  ======================= Martin Bazley ==========================

[toc] | [prev] | [next] | [standalone]


#2086

FromGazza <usenet@garethlock.com>
Date2012-08-15 17:01 -0700
Message-ID<9b11e4aa-c6f1-46a7-be01-9da6d75bbfd7@z6g2000vbc.googlegroups.com>
In reply to#2083
On Aug 14, 2:59 pm, Martin Bazley <martin.baz...@blueyonder.co.uk>
wrote:
> They don't.  They point to the addresses specified by sometextptr and
> tmpstr255ptr.  To make them point to the data contained in those
> addresses (i.e. sometext and tmpstr255), you should be using LDR
> instead.
>
> ADR, by the way, isn't a real instruction, it's just a convenient
> shorthand for assembler programmers.  "ADR Rx,address" assembles to the
> machine code for "ADD Rx,PC,(address-PC)" (or SUB, as appropriate),
> whatever the difference between address of the data and the address of
> the instruction happens to be at the point of assembly.  It doesn't
> *load* anything, and it has the same range limitations which affect the
> second operand of any instruction - which is why you're using
> sometextptr and tmpstr255ptr in the first place, to get around these
> limitations.  By storing your destination in memory in this way and
> using LDR *instead* of ADR (not using ADR all over again!), you free
> yourself from the ARM's limits on immediate constants.
>
> I believe we have had this particular conversation before.  Many times,
> in fact. I have particularly vivid memories of the time you accosted me
> at last year's London show and demanded that we had this conversation
> right now.
>

OK... Just couldn't remember whether it was ADR or LDR that was
required in this instance. The assembler side of things is still a
pretty new concept for me and I'm still learning on the job so to
speak.

[toc] | [prev] | [next] | [standalone]


#2091

FromGazza <usenet@garethlock.com>
Date2012-08-21 03:54 -0700
Message-ID<9a098389-5068-4b3c-8f26-a014e630d6d9@f17g2000vbz.googlegroups.com>
In reply to#2086
Now for something a little different... I'm performing a check on a
token in a stream of text, the token could be upper or lower case...
So I've written a simple loop to do the checking. The input is in a
buffer specified by a register using LDRB in the usual way to handle
the contents byte at a time. I also have a list of addresses in a jump
table to act on the results, I'm loading each of these at the
beginning of the loop using LDR Rx,[Ry],#4.

I need to know how to BEQ to an address held in a register in this
way.

I've tried

BEQ [Rx]

and

BEQ Rx

... neither compile.

Your help would be appreciated.

[toc] | [prev] | [next] | [standalone]


#2092

FromMartin <News03@avisoft.f9.co.uk>
Date2012-08-21 12:27 +0100
Message-ID<52c2b16e43News03@avisoft.f9.co.uk>
In reply to#2091
On 21 Aug, in article
<9a098389-5068-4b3c-8f26-a014e630d6d9@f17g2000vbz.googlegroups.com>,
   Gazza <usenet@garethlock.com> wrote:
> Now for something a little different... I'm performing a check on a
> token in a stream of text, the token could be upper or lower case...
> So I've written a simple loop to do the checking. The input is in a
> buffer specified by a register using LDRB in the usual way to handle
> the contents byte at a time. I also have a list of addresses in a jump
> table to act on the results, I'm loading each of these at the
> beginning of the loop using LDR Rx,[Ry],#4.

> I need to know how to BEQ to an address held in a register in this
> way.

> I've tried
> BEQ [Rx]
> and
> BEQ Rx

> ... neither compile.

Or even assemble! But it is not suprising.

The Assembler StrongHelp manual describes B as...
    Operation : PC = new address
    Syntax    : B{condition} expression

expression is not a register (which could be variable)! 
It is normally a label (ie constant).

One way to do it, if r11 has a number 0,1,2,..,n is to use...

CMP       r11,#(TableEnd-TableStart)/4
ADDLO     pc,pc,r11,LSL #2
B         error
.TableStart
B         Label0
B         Label1
.TableEnd

There will be other ways!

-- 
Martin Avison 
Note that unfortunately this email address will become invalid
without notice if (when) any spam is received. 

[toc] | [prev] | [next] | [standalone]


#2093

FromGazza <usenet@garethlock.com>
Date2012-08-21 05:08 -0700
Message-ID<f392e58a-a8b3-42ca-938a-260bfa53d9de@r9g2000vby.googlegroups.com>
In reply to#2092
On Aug 21, 12:27 pm, Martin <New...@avisoft.f9.co.uk> wrote:
> On 21 Aug, in article
> <9a098389-5068-4b3c-8f26-a014e630d...@f17g2000vbz.googlegroups.com>,
>    Gazza <use...@garethlock.com> wrote:
>
> > Now for something a little different... I'm performing a check on a
> > token in a stream of text, the token could be upper or lower case...
> > So I've written a simple loop to do the checking. The input is in a
> > buffer specified by a register using LDRB in the usual way to handle
> > the contents byte at a time. I also have a list of addresses in a jump
> > table to act on the results, I'm loading each of these at the
> > beginning of the loop using LDR Rx,[Ry],#4.
> > I need to know how to BEQ to an address held in a register in this
> > way.
> > I've tried
> > BEQ [Rx]
> > and
> > BEQ Rx
> > ... neither compile.
>
> Or even assemble! But it is not suprising.
>
> The Assembler StrongHelp manual describes B as...
>     Operation : PC = new address
>     Syntax    : B{condition} expression
>
> expression is not a register (which could be variable)!
> It is normally a label (ie constant).
>
> One way to do it, if r11 has a number 0,1,2,..,n is to use...
>
> CMP       r11,#(TableEnd-TableStart)/4
> ADDLO     pc,pc,r11,LSL #2
> B         error
> .TableStart
> B         Label0
> B         Label1
> .TableEnd
>
> There will be other ways!
>
> --
> Martin Avison
> Note that unfortunately this email address will become invalid
> without notice if (when) any spam is received.

The following code snippet is what I have. What I'm trying to achieve
is substitution of a token within a string with a value. On entry...

R0 --> Tokenised string.
R1 --> Output buffer.
R2 --> Output buffer size (bytes)
R3 --> Value to substitute.

Valid tokens are...

%%i<n> - Where <n> corresponds to a valid number for
OS_ConvertInteger<n>
%%h<n> - Where <n> corresponds to a valid number for OS_ConvertHex<n>
%%s<n> - Where <n> is the length of a zero terminated string pointed
to by R3.

The section of the routine I'm posting here is just the section that
interprets the character (i, h or s)...

                     ; Number of entries in token table.
   .str_substoknum   : EQUD     3

                     ; Legal characters in tokens. (Excluding numbers.
% MUST be 1st in list, CAPS equivalents
                     ; are calculated.)
   .str_substokentbl : EQUB     ASC("%")
                       EQUB     ASC("i"):EQUB     ASC("h"):EQUB
ASC("s")
                       ALIGN

                     ; Token handler jump table. Entries in this table
MUST be in the same order as they
                     ; appear in the token table above. (No handler
for %.)
   .str_subsjmptbl   : EQUD     str_substint
                       EQUD     str_substhex
                       EQUD     str_subststr

...

                       ADR      R8,str_substokentbl
                       MOV      R9,#1
                       ADR      R7,str_subsjmptbl
                       LDR      R11,str_substoknum
   .str_substdtok_lp : LDR      R10,[R7],#4
                       LDRB     R5,[R8,R9]
                       CMP      R4,R5
                      ;BEQ      R10                        ; This
doesn't work as is.
                      SUB      R5,R5,#32
                       CMP      R4,R5
                       ;BEQ      R10                        ; This
doesn't work as is.
                       ADD      R9,R9,#1
                       CMP      R9,R11
                       BLE      str_substdtok_lp



I know there is an OS call to do substitutions like this, but I'm
doing this purely as a learning exersise. Remember how Linux
started...

(Linux was Linus's personal project that he started purely to learn
386 asm.)

[toc] | [prev] | [next] | [standalone]


#2094

FromGazza <usenet@garethlock.com>
Date2012-08-21 05:25 -0700
Message-ID<7957f41c-c53b-4510-b835-e44477477c7d@x3g2000vbn.googlegroups.com>
In reply to#2093
                       ADR      R8,str_substokentbl
>                        MOV      R9,#1
>                        ADR      R7,str_subsjmptbl
>                        LDR      R11,str_substoknum
>    .str_substdtok_lp : LDR      R10,[R7],#4
>                        LDRB     R5,[R8,R9]
>                        CMP      R4,R5
>                       ;BEQ      R10                        ; This
> doesn't work as is.
>                       SUB      R5,R5,#32
>                        CMP      R4,R5
>                        ;BEQ      R10                        ; This
> doesn't work as is.
>                        ADD      R9,R9,#1
>                        CMP      R9,R11
>                        BLE      str_substdtok_lp

Think I've answered my own question...

Would

MOVEQ PC,R10

work, instead of

BEQ R10

?

[toc] | [prev] | [next] | [standalone]


#2095

FromGazza <usenet@garethlock.com>
Date2012-08-21 08:23 -0700
Message-ID<767a801a-a30c-41a2-bcd3-3108f87b3399@ft6g2000vbb.googlegroups.com>
In reply to#2094
This is a complete dump of the routine...

      10 :   ; Parse a string containing a token and substitute the
contents of R3. This call currently deals with
      20 :   ; one token at a time and will return after substituting
the 1st token found. To substitute more than
      30 :   ; one token in the same string, just modify R1 & R2 on
exit, put the next value in R3 and call again.
      40 :   ; Token format is as follows...
      50 :
      60 :   ; R0 --> Pointer to zero-terminated tokenised string.
      70 :   ; R1 --> Pointer to output buffer.
      80 :   ; R2 --> Size of output buffer.
      90 :   ; R3 --> Depends on token found in string pointed to by
R0.
     100 :
     110 :   ; %%i<n>   = Where <n> follows the OS_ConvertInteger<n>
specs.         R3 --> Integer value.
     120 :   ; %%h<n>   = Where <n> follows the OS_ConvertHex<n>
specs.             R3 --> Integer value.
     130 :   ; %%s<n>   = Where <n> is the length of a zero-terminated
string.      R3 --> String pointer.
     140 :
     150 :   ; R0 <-- Pointer to zero-terminated tokenised string.
(Points to character after token just substituted.)
     160 :   ; R1 <-- Preserved.
     170 :   ; R2 <-- Length of string in output buffer.
     180 :   ; R3 <-- Free space in output buffer.
     190 :
     200 :   .str_subst        : STMFD    SP!,{R1,R4-R12,LR}
     210 :                       MOV      R12,R2                     ;
Keep copy of buffer length.
     220 :                       ADR      R8,str_substokentbl
     230 :                       LDRB     R5,[R8]
     240 :   .str_subst_lp     : MOV      R9,#0
     250 :                       MOV      R10,#0
     260 :                       ADR      R6,str_substokbuf
     270 :   .str_subst_lp2    : CMP      R10,#6                     ;
Clear token buffer.
     280 :                       STRNEB   R9,[R6],#1
     290 :                       ADDNE    R10,R10,#1
     300 :                       BNE      str_subst_lp2
     310 :                       LDRB     R4,[R0],#1                 ;
Get next byte.
     320 :                       CMP      R4,#0
     330 :                       BEQ      str_subst_exit
     340 :                       CMP      R4,R5
     350 :                       BEQ      str_substtoken
     360 :                       STRB     R4,[R1],#1
     370 :                       SUB      R12,R12,#1                 ;
Decrement our free space count.
     380 :                       B        str_subst_lp
     390 :
     400 :                     ; We have found a % in the input
string, start filling token buffer.
     410 :
     420 :   .str_substtoken   : ADR      R6,str_substokbuf
     430 :                       MOV      R7,#1
     440 :                       STRB     R4,[R6],#1
     450 :                       LDRB     R4,[R0],#1
     460 :                       CMP      R4,#ASC("%")               ;
Look for second "%".
     470 :                       BNE      str_substnotoken
     480 :
     490 :   .str_substgettok  : CMP      R4,#0                      ;
Found zero-termination.
     500 :                       BEQ      str_subst_exit
     510 :                       CMP      R4,#32                     ;
SPACE ASCII (32) indicated end of token.
     520 :                       BEQ      str_substdetok
     530 :                       CMP      R4,#13                     ;
CR    ASCII (13) indicated end of token.
     540 :                       BEQ      str_substdetok
     550 :                       CMP      R4,#10                     ;
LF    ASCII (10) indicated end of token.
     560 :                       BEQ      str_substdetok
     570 :                       ADD      R7,R7,#1
     580 :                       CMP      R7,#7                      ;
We have max token length, try and decode.
     590 :                       BGT      str_substdetok
     600 :                       STRB     R4,[R6],#1                 ;
Otherwise store byte in token buffer.
     610 :                       LDRB     R4,[R0],#1                 ;
Get next byte.
     620 :                       B        str_substgettok            ;
Jump back to process it.
     630 :
     640 :                     ; We have what appears to be a token in
the buffer.
     650 :
     660 :   .str_substdetok   : ADR      R6,str_substokbuf          ;
Stick pointer to start of token buffer in R6.
     670 :                       LDRB     R4,[R6]
     680 :                       CMP      R4,#ASC("%")
     690 :                       BNE      str_substnotoken
     700 :                       LDRB     R4,[R6,#1]
     710 :                       CMP      R4,#ASC("%")
     720 :                       BNE      str_substnotoken
     730 :                       LDRB     R4,[R6,#2]
     740 :                       ADR      R8,str_substokentbl
     750 :                       MOV      R9,#1
     760 :                       ADR      R7,str_subsjmptbl
     770 :                       LDR      R11,str_substoknum
     780 :   .str_substdtok_lp : LDR      R10,[R7],#4
     790 :                       LDRB     R5,[R8,R9]
     800 :                       CMP      R4,R5
     810 :                       MOVEQ
PC,R10                      ; ??
     820 :                       SUB      R5,R5,#32
     830 :                       CMP      R4,R5
     840 :                       MOVEQ
PC,R10                      ; ??
     850 :                       ADD      R9,R9,#1
     860 :                       CMP      R9,R11
     870 :                       BLE      str_substdtok_lp
     880 :
     890 :                     ; If token buffer appears to be invalid
token, then we need to copy it to the output
     900 :                     ; buffer anyway.
     910 :
     920 :   .str_substnotoken : ADR      R6,str_substokbuf          ;
Stick pointer to start of token buffer in R6.
     930 :                       BL       str_subst_cpybuf           ;
Do the copy.
     940 :                       B        str_subst_lp2              ;
Jump back to main loop.
     950 :
     960 :   ; Start of token jump table handlers...
     970 :   ; These addresses are the handlers for the various
tokens. All handlers that deal with numerics are to
     980 :   ; stick the resulting string pointer in R3 before jumping
to str_subst_reload to copy the string to the
     990 :   ; buffer.
    1000 :
    1010 :                     ; Substitute token for an integer value
in R3 into the text stream.
    1020 :   .str_subst_int    : ADR      R6,str_substokbuf
    1030 :                       STMFD    SP!,{R0-R3}
    1040 :                       MOV      R1,#ASC("0")
    1050 :                       MOV      R2,#ASC("9")
    1060 :   .str_subst_int_lp : LDRB     R0,[R6],#1
    1070 :                       CMP      R0,#0
    1080 :                       BEQ      str_substnotoken
    1090 :                       BL       str_rangeeq
    1100 :                       CMP      R3,#1
    1110 :                       BNE      str_subst_int_lp
    1120 :                       SUB      R0,R0,#ASC("0")
    1130 :
    1140 :                     ; R0 now contains the digit.
    1150 :
    1160 :                       ADR      R7,str_subst_intjpt        ;
Point R7 to the start of the jump table.
    1170 :                       LDR      R8,str_subsval             ;
Point R8 to the table containing valid values.
    1180 :                       LDR      R9,str_subsval_sz          ;
Number of valid values & jump-table entries.
    1190 :   .str_subst_int_ck : LDR      R10,[R7],#4
    1200 :                       LDRB     R4,[R8],#1
    1210 :                       SUB      R9,R9,#1
    1220 :                       CMP      R0,R4                      ;
Compare our digit to our table of values.
    1230 :                       LDMEQFD  SP!,{R0-R3}
    1240 :                       MOVEQ    PC,R10                     ;
Jump to jump-table entry corresponding value.
    1250 :                       CMP      R9,#0
    1260 :                       BNE      str_subst_int_ck
    1270 :                       LDMFD    SP!,{R0-R3}
    1280 :                       B        str_subst_err
    1290 :
    1300 :                     ; str_subst_int jump-table...
    1310 :
    1320 :   .str_subst_intjpt : EQUD     str_subst_int1
    1330 :                       EQUD     str_subst_int2
    1340 :                       EQUD     str_subst_int3
    1350 :                       EQUD     str_subst_int4
    1360 :
    1370 :                     ; Start of integer jump-table
handlers...
    1380 :
    1390 :   .str_subst_int1   : STMFD    SP!,{R0-R4}                ;
OS_ConvertInteger1
    1400 :                       MOV      R0,R3
    1410 :                       ADR      R1,str_valstr
    1420 :                       MOV      R2,#29
    1430 :                       SWI      "OS_ConvertInteger1"
    1440 :                       LDMFD    SP!,{R0-R4}
    1450 :                       B        str_subst_reload
    1460 :
    1470 :   .str_subst_int2   : STMFD    SP!,{R0-R4}                ;
OS_ConvertInteger2
    1480 :                       MOV      R0,R3
    1490 :                       ADR      R1,str_valstr
    1500 :                       MOV      R2,#29
    1510 :                       SWI      "OS_ConvertInteger2"
    1520 :                       LDMFD    SP!,{R0-R4}
    1530 :                       B        str_subst_reload
    1540 :
    1550 :   .str_subst_int3   : STMFD    SP!,{R0-R4}                ;
OS_ConvertInteger3
    1560 :                       MOV      R0,R3
    1570 :                       ADR      R1,str_valstr
    1580 :                       MOV      R2,#29
    1590 :                       SWI      "OS_ConvertInteger3"
    1600 :                       LDMFD    SP!,{R0-R4}
    1610 :                       B        str_subst_reload
    1620 :
    1630 :   .str_subst_int4   : STMFD    SP!,{R0-R4}                ;
OS_ConvertInteger4
    1640 :                       MOV      R0,R3
    1650 :                       ADR      R1,str_valstr
    1660 :                       MOV      R2,#29
    1670 :                       SWI      "OS_ConvertInteger4"
    1680 :                       LDMFD    SP!,{R0-R4}
    1690 :                       B        str_subst_reload
    1700 :
    1710 :                     ; Substitute token for a hex value in
R3 into the text stream.
    1720 :   .str_subst_hex    : MOV      R0,R0                      ;
Convert and copy to str_valstr.
    1730 :                       STMFD    SP!,{R0-R3}
    1740 :                       MOV      R1,#ASC("0")
    1750 :                       MOV      R2,#ASC("9")
    1760 :   .str_subst_hex_lp : LDRB     R0,[R6],#1
    1770 :                       CMP      R0,#0
    1780 :                       BEQ      str_substnotoken
    1790 :                       BL       str_rangeeq
    1800 :                       CMP      R3,#1
    1810 :                       BNE      str_subst_hex_lp
    1820 :                       SUB      R0,R0,#ASC("0")
    1830 :
    1840 :                     ; R0 now contains the digit.
    1850 :
    1860 :                       ADR      R7,str_subst_hexjpt        ;
Point R7 to the start of the jump table.
    1870 :                       LDR      R8,str_subsvalh            ;
Point R8 to the table containing valid values.
    1880 :                       LDR      R9,str_subsvalh_sz         ;
Number of valid values & jump-table entries.
    1890 :   .str_subst_hex_ck : LDR      R10,[R7],#4
    1900 :                       LDRB     R4,[R8],#1
    1910 :                       SUB      R9,R9,#1
    1920 :                       CMP      R0,R4                      ;
Compare our digit to our table of values.
    1930 :                       LDMEQFD  SP!,{R0-R3}
    1940 :                       MOVEQ    PC,R10                     ;
Jump to jump-table entry corresponding value.
    1950 :                       CMP      R9,#0
    1960 :                       BNE      str_subst_hex_ck
    1970 :                       B        str_subst_err
    1980 :
    1990 :   .str_subst_hex1   : MOV      R0,R0                      ;
OS_ConvertHex1
    2000 :                       B        str_subst_reload
    2010 :
    2020 :   .str_subst_hex2   : MOV      R0,R0                      ;
OS_ConvertHex2
    2030 :                       B        str_subst_reload
    2040 :
    2050 :   .str_subst_hex4   : MOV      R0,R0                      ;
OS_ConvertHex4
    2060 :                       B        str_subst_reload
    2070 :
    2080 :   .str_subst_hex6   : MOV      R0,R0                      ;
OS_ConvertHex6
    2090 :                       B        str_subst_reload
    2100 :
    2110 :   .str_subst_hex8   : MOV      R0,R0                      ;
OS_ConvertHex8
    2120 :                       B        str_subst_reload
    2130 :
    2140 :   .str_subst_hexjpt : EQUD     str_subst_hex1
    2150 :                       EQUD     str_subst_hex2
    2160 :                       EQUD     str_subst_hex4
    2170 :                       EQUD     str_subst_hex6
    2180 :                       EQUD     str_subst_hex8
    2190 :
    2200 :                     ; Substitute token for a text string
pointed to by R3.
    2210 :   .str_subst_reload : LDR      R3,str_valstr              ;
Re-load pointer into R3.
    2220 :   .str_subst_str    : STMFD    SP!,{R0,R1,R3}
    2230 :                       MOV      R0,R3
    2240 :                       BL       str_strlen
    2250 :                       MOV      R10,R1
    2260 :                       CMP      R1,R12
    2270 :                       LDMFD    SP!,{R0,R1,R3}
    2280 :                       BGT      str_subst_err              ;
Bail with oVerflow set if string in R3 too long.
    2290 :                       STMFD    SP!,{R0,R2,R3}
    2300 :                       MOV      R0,R3
    2310 :                       MOV      R2,R12
    2320 :                       BL       str_strcpy
    2330 :                       LDMFD    SP!,{R0,R2,R3}
    2340 :                       MOV      R3,R10
    2350 :                       SUB      R3,R12,R3
    2360 :                       STMFD    SP!,{R0,R1}
    2370 :                       MOV      R0,R1
    2380 :                       BL       str_strlen
    2390 :                       MOV      R10,R1
    2400 :                       LDMFD    SP!,{R0,R1}
    2410 :                       MOV      R2,R10
    2420 :                       B        str_subst_exit2
    2430 :
    2440 :   ; Exit routine, if our token buffer isn't null, then copy
to output before we bail.
    2450 :
    2460 :   .str_subst_exit   : ADR      R6,str_substokbuf          ;
Stick pointer to start of token buffer in R6.
    2470 :                       LDRB     R4,[R6]
    2480 :                       CMP      R4,#0
    2490 :                       LDMEQFD  SP!,{R1,R4-R12,PC}
    2500 :                       BL       str_subst_cpybuf
    2510 :                       STMFD    SP!,{R0,R1}
    2520 :                       MOV      R0,R6
    2530 :                       BL       str_strlen
    2540 :                       MOV      R4,R1
    2550 :                       LDMFD    SP!,{R0,R1}
    2560 :                       ADD      R0,R0,R4
    2570 :   .str_subst_exit2  : LDMFD    SP!,{R1,R4-R12,PC}
    2580 :
    2590 :   .str_subst_err    : CMP      R0,#1<<31
    2600 :                       CMNVC    R0,#1<<31
    2610 :                       LDMFD    SP!,{R1,R4-R12,PC}

Sorry, but you'll need to view as fixed width font to see it properly.
I've only filled in the 4 OS_ConvertInteger handlers and the string
handler at the moment.

Routines called by this code...

str_strcpy - Copies a zero-terminated string from one buffer to
another.
str_strlen - Returns the length of a zero-terminated string.

I think I've missed the master token jump-table off the top of this...
This is just one of the ancillary routines defined in my assembler re-
write of LibASH that I'm currently experimenting with. I'll dump a
whole copy of the file to it's usual location when I return home.

[toc] | [prev] | [next] | [standalone]


#2097

Fromdruck <news@druck.org.uk>
Date2012-08-21 18:19 +0100
Message-ID<k10fui$n3t$1@dont-email.me>
In reply to#2091
On 21/08/2012 11:54, Gazza wrote:

[Snip]

> I'm loading each of these at the
> beginning of the loop using LDR Rx,[Ry],#4.
>
> I need to know how to BEQ to an address held in a register in this
> way.
>
> I've tried
>
> BEQ [Rx]
>
> and
>
> BEQ Rx
>
> ... neither compile.

You can't just make assembler up as you go along! You need to study the 
book long and hard before going near the computer. I'm not being unkind, 
but it is so easy to crash the machine with assembler, you have to know 
it inside out in order not to spend your life trying to debug flaky code.

The correct answer is to load the jump address straight in to the 
program counter (R15) e.g. LDR R15,[Ry],#4

---druck

[toc] | [prev] | [next] | [standalone]


#2102

FromGazza <usenet@garethlock.com>
Date2012-08-21 14:20 -0700
Message-ID<efe84adb-2369-4c99-b420-b666d5da7f4e@q22g2000vbx.googlegroups.com>
In reply to#2097
On Aug 21, 6:19 pm, druck <n...@druck.org.uk> wrote:
> On 21/08/2012 11:54, Gazza wrote:
>
> [Snip]
>
> > I'm loading each of these at the
> > beginning of the loop using LDR Rx,[Ry],#4.
>
> > I need to know how to BEQ to an address held in a register in this
> > way.
>
> > I've tried
>
> > BEQ [Rx]
>
> > and
>
> > BEQ Rx
>
> > ... neither compile.
>
> You can't just make assembler up as you go along! You need to study the
> book long and hard before going near the computer. I'm not being unkind,
> but it is so easy to crash the machine with assembler, you have to know
> it inside out in order not to spend your life trying to debug flaky code.
>
> The correct answer is to load the jump address straight in to the
> program counter (R15) e.g. LDR R15,[Ry],#4
>
> ---druck

Using R15 like that, is that 32bit compliant? Wouldn't using LDR Rx,
[Ry],#4 : MOV PC,Rx or even LDR PC,[Ry],#4 avoid headaches? Maybe I'm
barking up the wrong tree, I'm just trying to understand this.

And... Yeah, I like setting myself challenges. Didn't you get that
idea from me trying to re-write UMoria in BBC BASIC... lol

[toc] | [prev] | [next] | [standalone]


#2104

Fromcferris@freeRemoveuk.com.invalid
Date2012-08-22 09:07 +0100
Message-ID<54ea22c352.cferris@cferris.freeuk.com>
In reply to#2102
In message <efe84adb-2369-4c99-b420-b666d5da7f4e@q22g2000vbx.googlegro 
ups.com>
          Gazza <usenet@garethlock.com> wrote:

> On Aug 21, 6:19 pm, druck <n...@druck.org.uk> wrote:
>> On 21/08/2012 11:54, Gazza wrote:
>>
[Snip]


> Using R15 like that, is that 32bit compliant? Wouldn't using LDR Rx,
> [Ry],#4 : MOV PC,Rx or even LDR PC,[Ry],#4 avoid headaches?

PC = pc = R15 = 15 = &F



-- 
Colin Ferris Cornwall UK

[toc] | [prev] | [next] | [standalone]


#2107

FromGazza <usenet@garethlock.com>
Date2012-08-22 05:28 -0700
Message-ID<eecf112c-6756-43f8-87c7-ed98cc2809fb@s2g2000vbj.googlegroups.com>
In reply to#2104
On Aug 22, 9:07 am, cfer...@freeRemoveuk.com.invalid wrote:
> In message <efe84adb-2369-4c99-b420-b666d5da7...@q22g2000vbx.googlegro
> ups.com>
>           Gazza <use...@garethlock.com> wrote:
>
> > On Aug 21, 6:19 pm, druck <n...@druck.org.uk> wrote:
> >> On 21/08/2012 11:54, Gazza wrote:
>
> [Snip]
>
> > Using R15 like that, is that 32bit compliant? Wouldn't using LDR Rx,
> > [Ry],#4 : MOV PC,Rx or even LDR PC,[Ry],#4 avoid headaches?
>
> PC = pc = R15 = 15 = &F
>
> --
> Colin Ferris Cornwall UK

Correct me if I'm wrong, but doesn't PC specify the section of R15
that contains the Program Counter, as opposed to R15 that contains the
Program Counter AND the PSR. (On 26 bit anyhow.) I want to try and
make this 32bit safe, rather than 26bit incompatible.

[toc] | [prev] | [next] | [standalone]


#2109

FromSteve Fryatt <news@stevefryatt.org.uk>
Date2012-08-22 14:47 +0100
Message-ID<mpro.m95szm05v5dow01iy.news@stevefryatt.org.uk>
In reply to#2107
On 22 Aug, Gazza wrote in message
    <eecf112c-6756-43f8-87c7-ed98cc2809fb@s2g2000vbj.googlegroups.com>:

> On Aug 22, 9:07 am, cfer...@freeRemoveuk.com.invalid wrote:
>
> > PC = pc = R15 = 15 = &F
>
> Correct me if I'm wrong, but doesn't PC specify the section of R15 that
> contains the Program Counter, as opposed to R15 that contains the Program
> Counter AND the PSR. (On 26 bit anyhow.)

No, PC, R15 and 15 are synonymous.

> I want to try and make this 32bit safe, rather than 26bit incompatible.

That's a separate issue.

-- 
Steve Fryatt - Leeds, England

http://www.stevefryatt.org.uk/

[toc] | [prev] | [next] | [standalone]


#2110

Fromdruck <news@druck.org.uk>
Date2012-08-22 23:11 +0100
Message-ID<k13ler$56c$1@dont-email.me>
In reply to#2102
On 21/08/2012 22:20, Gazza wrote:
> On Aug 21, 6:19 pm, druck <n...@druck.org.uk> wrote:
>> The correct answer is to load the jump address straight in to the
>> program counter (R15) e.g. LDR R15,[Ry],#4
>>

> Using R15 like that, is that 32bit compliant? Wouldn't using LDR Rx,
> [Ry],#4 : MOV PC,Rx or even LDR PC,[Ry],#4 avoid headaches? Maybe I'm
> barking up the wrong tree, I'm just trying to understand this.

No, it is fine in both 26bit and 32bit modes, and there is no need to 
ever use a load and separate move to PC.

If you read the book (like Cockrell's) you see that in 26bit modes when 
R15 is used as the destination only the program counter is written to. 
There are various rules as to when the flags are or are not visible when 
R15 is used as a source. You've got to know these things to write 
working code.

---druck

[toc] | [prev] | [next] | [standalone]


#2124

FromMartin Bazley <martin.bazley@blueyonder.co.uk>
Date2012-08-29 18:36 +0100
Message-ID<34e1f1c652.martin@blueyonder.co.uk>
In reply to#2110
The following bytes were arranged on 29 Aug 2012 by Gazza :

> Does that mean that to get values as opposed to strings, I need to
> double load?

Your misconception lies in thinking that "strings" are a concept in
their own right, as opposed to simply a number of "values" stored after
each other.  This is almost certainly a bad habit you learned from
BASIC.

The EQUS operator is nothing more than a convenient shorthand, like ADR.

EQUS "Some text"+CHR$(0):ALIGN

Is equivalent to:

EQUB 83
EQUB 111
EQUB 109
EQUB 101
EQUB 32
EQUB 116
EQUB 101
EQUB 120
EQUB 116
EQUB 0
EQUB 0
EQUB 0

One of the common threads in your posts, such as this one, is that you
have serious conceptual problems with the idea of pointers[1], which is
something you simply cannot have your knickers in a twist about if you
are to have any hope of succeeding in assembler.  See also: ADR versus
LDR.

Your problems are not with assembler, but are more deeply rooted in some
of the fundamental concepts of programming as a whole.  Assembler simply
happens to be the language you are currently attempting to learn.

[1] I pray he never finds out about C...
-- 
  __<^>__   === RISC OS is a work of art.  Some people adore it,  ===
 / _   _ \  === others can't see the point of it, and it's really ===
( ( |_| ) ) === expensive.                                        ===
 \_>   <_/  ======================= Martin Bazley ===================

[toc] | [prev] | [next] | [standalone]


#2105

FromJeremy Nicoll - news posts <jn.nntp.scrap007@wingsandbeaks.org.uk>
Date2012-08-22 09:38 +0100
Message-ID<mpro.m95eog001lbtj00g4@wingsandbeaks.org.uk.invalid>
In reply to#2091
Gazza <usenet@garethlock.com> wrote:

>Now for something a little different...

Is there any chance you could start some new threads occasionally?  This one
is so far indented to the right here that it's getting hard to see who
replied to what...

-- 
Jeremy C B Nicoll - my opinions are my own.

Email sent to my from-address will be deleted. Instead, please reply
to newsreplyaaa@wingsandbeaks.org.uk replacing "aaa" by "284".  

[toc] | [prev] | [next] | [standalone]


#2037

Fromjgh@arcade.demon.co.uk (Jonathan Graham Harston)
Date2012-08-08 23:15 +0100
Message-ID<120808235501@arcade.demon.co.uk>
In reply to#2016
martin.bazley wrote:
> There is no difference between the OS_GetEnv SWI and the HIMEM keyword -
> they perform exactly the same function.  Just use OS_GetEnv.
 
No they don't. When BASIC starts up HIMEM is initialised to the
return value from OS_GetEnv. That is all. If you do HIMEM=HIMEM-16384
and then read HIMEM it will be different to the return value from
OS_GetEnv. OS_GetEnv returns the top of the environment's memory
area. HIMEM returns the top of BASIC's memory area.
 
-- 
J.G.Harston - jgh@mdfs.net - mdfs.net/jgh
Sheffield Parliamentary Boundary Review - http://mdfs.net/per13

[toc] | [prev] | [next] | [standalone]


#2040

FromMartin Bazley <martin.bazley@blueyonder.co.uk>
Date2012-08-09 13:59 +0100
Message-ID<d8c98bbc52.martin@blueyonder.co.uk>
In reply to#2037
The following bytes were arranged on 8 Aug 2012 by Jonathan Graham Harston:

> martin.bazley wrote:
> > There is no difference between the OS_GetEnv SWI and the HIMEM keyword -
> > they perform exactly the same function.  Just use OS_GetEnv.
>
> No they don't. When BASIC starts up HIMEM is initialised to the
> return value from OS_GetEnv. That is all. If you do HIMEM=HIMEM-16384
> and then read HIMEM it will be different to the return value from
> OS_GetEnv. OS_GetEnv returns the top of the environment's memory
> area. HIMEM returns the top of BASIC's memory area.

On the other hand, there is no way HIMEM can be greater than the
OS_GetEnv value, as it is the start address of the stack.  Coupled with
the fact that no-one uses the HIMEM= syntax, I do not think this is too
concerning.

-- 
  __<^>__
 / _   _ \  I don't have a problem with God; it's his fan club I can't stand.
( ( |_| ) )
 \_>   <_/  ======================= Martin Bazley ==========================

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.sys.acorn.programmer


csiph-web