Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.sys.acorn.programmer > #1905 > unrolled thread
| Started by | Gazza <usenet@garethlock.com> |
|---|---|
| First post | 2012-07-10 07:09 -0700 |
| Last post | 2012-07-11 09:26 +0100 |
| Articles | 20 on this page of 63 — 18 participants |
Back to article view | Back to comp.sys.acorn.programmer
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 →
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | Chris Johnson <chrisjohnson+news@spamcop.net> |
|---|---|
| Date | 2012-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]
| From | Martin Bazley <martin.bazley@blueyonder.co.uk> |
|---|---|
| Date | 2012-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]
| From | Martin Bazley <martin.bazley@blueyonder.co.uk> |
|---|---|
| Date | 2012-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]
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | Martin <News03@avisoft.f9.co.uk> |
|---|---|
| Date | 2012-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]
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | druck <news@druck.org.uk> |
|---|---|
| Date | 2012-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]
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | cferris@freeRemoveuk.com.invalid |
|---|---|
| Date | 2012-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]
| From | Gazza <usenet@garethlock.com> |
|---|---|
| Date | 2012-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]
| From | Steve Fryatt <news@stevefryatt.org.uk> |
|---|---|
| Date | 2012-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]
| From | druck <news@druck.org.uk> |
|---|---|
| Date | 2012-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]
| From | Martin Bazley <martin.bazley@blueyonder.co.uk> |
|---|---|
| Date | 2012-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]
| From | Jeremy Nicoll - news posts <jn.nntp.scrap007@wingsandbeaks.org.uk> |
|---|---|
| Date | 2012-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]
| From | jgh@arcade.demon.co.uk (Jonathan Graham Harston) |
|---|---|
| Date | 2012-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]
| From | Martin Bazley <martin.bazley@blueyonder.co.uk> |
|---|---|
| Date | 2012-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