flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Load and Store problem

Author
Thread Post new topic Reply to topic
pipifax



Joined: 04 Aug 2023
Posts: 5
pipifax 07 Jul 2025, 19:19
Code:
; This project aims to build a binary FORS(R) capable to execute or compile
;text input from keyboard or file. Typical commands for the build are shown
;in lines 6 to 13 of forsr.asm file - in submitted forsr.zip archive.
; As an aid for the builder to include /leave out parts of the source file,
;I wanted to add a reference table to the compilation output, showing how
;often each function has been called by any other. This reftable is the
;very topic of this blog.
; The following additions have been made to file forsr.inc : 
virtual at 0
refs::
 dw 0 dup  16
 dw 0 dup 128
 dw 0 dup 400 
end virtual
; This array size reflects the current size of FORS. A theoretical limit
;would allow for 2^15-1 function-calls=refs, so entries would need only
;15 bits for ref-count, and the msbit can be used to flag the functions'
;invisibility (to users of FORS).
; FORS functions (during build process) are FASM symbols of 4 characters.
;These may be referred to as the assembly or meta name, as parameter 'nam'. 
;When a function 'myfc' is defined, its array location will be named 'rmyfc'.
;There are 2 macros, P and H, for function definitions. P uses assembly code,
;these functions do not make references and are placed before all H-made
;ones, which are mere lists of references to P- and other H-functions.
; The number of P-functions is currently limited to 14+2spare+128, while the
;set of H-type ones is, assisted by reftable, managed by the builder and,
;to a lesser degree, the user. 
macro h nam,..{;here restricted to reftable functionality.
a#nam: name equ nam
nam=expression($)
r#nam=288+pt*2;pt is a global variable
pt=pt+1;prepare for next definition
}
;If myfc is being referred to, refs:rmyfc must have 1 added to for any ref.
;If myfc is to be invisible, H must set the sign bit of refs:rmyfc .
;Both operations are implemented by:
macro ixr xa,xi=1{;increment refs:xa
 if defined `xa
 load xd word from refs:xa
 store word xd+xi at refs:xa
 end if }
; However, H-functions may be refered to before being defined!
;This is the reason why we use assemblers, and especially FASM,
;which excels in symbol resolution and macro features.
;But all load and store instructions such as in IXR
;raise "error: value out of range". The only sensible reason for
;this message is that xa would be undefined or outside the array.
;The FASM 1.72 Programmer's Manual suggests to use "assert 0",
;but this did not provide an improvement. Instead, I used
irpv n,name { display 10
 forward
 if defined r#n
  display `n,32
  p4 r#n
 end if
}
;at the end of forsr.asm . This, I think, makes sure that all
;assembly names and their associated r#n labels are defined.
; When every call of IXR is commented out (in file forsr.inc) the
;compilation succeeds and the printout shows all assembly names,
;and their labels are present and correct. So my question is:
;???   IS THERE ANY (FORMAL) ERROR in REFS: or IXR   ???
;PLEASE EXPLAIN why loads and stores to refs: do not work!!!
; The files, as described before (reftable defined, initialized,
;r#n labels defined and printed at the end of file forsr.txt)
;have been combined into archive FORS.ZIP .

;The following macro PR, was planned to be called as last activitiy of
;compilation to to get the final result, as promised by comment:
macro pr {;print table of all reference counts
;?  Is it correct to use "r\#n" and "\}" ?
 irpv n,name
  if defined r\#n
   if r\#n in <0,32,288>
    display 10
   else
    display 32
   end if
   display `n,32
   load xd word from refs:r\#n
   display xd/8000h*2+'+'
   pz xd mod 8000h
\} }
; PR uses an equivalent load command as IXR and calling it would show
;the same error message. But I tried printing "experimentally" in some
;undocumented ways, there were partial results:
- The numbers were always shown as 0, even when initialized >0.
- The "in" condition was never true (no linefeeds printed to separate
  the "subranges"). As if 0, 32, 288 had never occured!    
Edit by revolution: Added code tags


Description: Contents and use of files are explained in main text.
Download
Filename: forsr.zip
Filesize: 108.56 KB
Downloaded: 58 Time(s)



Last edited by pipifax on 08 Jul 2025, 20:11; edited 1 time in total
Post 07 Jul 2025, 19:19
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20708
Location: In your JS exploiting you and your system
revolution 07 Jul 2025, 23:34
To start with the last question: 'The "in" condition was never true (no linefeeds printed to separate the "subranges"). As if 0, 16, 288 had never occured!'.

in compares tokens. It doesn't compare values. See this code:
Code:
x=1
if x in <1>
 display 'x = 1',0xa
end if    
Code:
flat assembler  version 1.73.31  (16384 kilobytes memory)
1 passes, 0 bytes.    
To detect specific values, use something like this:
Code:
x=1
if x = 0 | x = 1
 display 'x=0 or x=1',0xa
end if    
Code:
flat assembler  version 1.73.31  (16384 kilobytes memory)
x=0 or x=1
1 passes, 0 bytes.    
Post 07 Jul 2025, 23:34
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4260
Location: vpcmpistri
bitRAKE 08 Jul 2025, 05:21
The duplicated values follow the count of duplication:
Code:
virtual at 0
refs::
 dw 16 dup 0
 dw 128 dup 0
 dw 400 dup 0
end virtual    
... this solved problem for me.
Post 08 Jul 2025, 05:21
View user's profile Send private message Visit poster's website Reply with quote
pipifax



Joined: 04 Aug 2023
Posts: 5
pipifax 08 Jul 2025, 19:49
revolution:
I do not think we disagree. My code (... in<0,16,288>) was intended to detect 1 of 3 values and, in case of a match, issue a linefeed in place of a blank. However, there is a numerical mistake. I should have used <0,32,288>. These are the byte offsets at the beginning of the 1st, 2nd and 3rd "subgroup" of 16, 128 and 400 (is don't care here): 0=start of refs, 32=16*2, 288=16*2+128*2.
Yet, because of the first 0, I had expected a linefeed at start of printing as the first value of r#n is 0. I took this missing linefeed as a hint, that there was something wrong with r#n in principle. But your post taught me to replace that number 16. Thank you.
bitRAKE:
What I wanted to code: 16 words =0, 128 words =0, and 400 words =0 again. The split was made to document and remember the size of 3 subarrays. The last one, as can be seen from my text, is used by macro H, where the lines "r#nam=288+pt*2" (pt starts at 0) and "pt=pt+1" serve to set up the 3rd subrange for symbols defined by H.
I also checked my file forsr.asm to find that 2 byte arrays also use "db count dup 0" - same order of count and value. If I had erroneously reversed this order in case of refs: , this would have been a fine solution for load and store to malfunction. Thanks anyway.
Post 08 Jul 2025, 19:49
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4260
Location: vpcmpistri
bitRAKE 09 Jul 2025, 02:29
pipifax wrote:
Code:
virtual at 0
refs::
 dw 0 dup  16
 dw 0 dup 128
 dw 0 dup 400 
end virtual
    
pipifax wrote:
So my question is:
;??? IS THERE ANY (FORMAL) ERROR in REFS: or IXR ???
;PLEASE EXPLAIN why loads and stores to refs: do not work!!!
... if having correct counts in "refs" is not the goal then it completely goes over my head. Because when I assemble ...
Code:
virtual at 0 as 'refs'
refs::
 dw 16 dup 0
 dw 128 dup 0
 dw 400 dup 0
 sizeof.refs = $
end virtual    
... and I examine the "refs" file, the counts are present. I've not verified their correctness - perhaps the values are incorrect?

Furthermore, I can assemble:
Code:
macro ixr xa,xi=1 {;add refs:xa xi
 if ~ defined xa
  display 10,9,`xa,' undefined!',10
 else if xa < sizeof.refs
  load xd word from refs:xa
  store word xd+xi at refs:xa
 else
  display 10,9,`xa,'('
  temp = 1
  while temp < xa
   temp = temp * 10
  end while
  while temp <> 1
   temp = temp/10
   display '0' + ((xa/temp) mod 10)
  end while
  display ') out of bounds!',10
 end if
}    
... and see no error in the output.

Please, state again the bounds error you are seeing? If "refs::" has a size of zero then a bounds error is quite understandable. If you want "refs::" to grow dynamically then a delayed size variable would be needed.

_________________
¯\(°_o)/¯ AI may [not] have aided with the above reply.
Post 09 Jul 2025, 02:29
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20708
Location: In your JS exploiting you and your system
revolution 09 Jul 2025, 20:28
pipifax wrote:
revolution:
I do not think we disagree. My code (... in<0,16,288>) was intended to detect 1 of 3 values ...
in doesn't compare values. The code I posted shows that any value the variable has is ignored. This is because it compares tokens, which in the case for this thread the token is the name or the variable, not the value of the variable.
Post 09 Jul 2025, 20:28
View user's profile Send private message Visit poster's website Reply with quote
pipifax



Joined: 04 Aug 2023
Posts: 5
pipifax 09 Jul 2025, 20:35
bitRAKE:
I tried to correct some typos and errors in red, but text is still black.
Please stay patient when I repeat. The project (as submitted in forsr.zip: all calls of IXR outcommented, no other LOAD or STORE from/at refs:) compiles without error. To provoke the reported error, I restored "ixr rtjmp" of file forsr.inc (this triggers, per contents of forsr.asm, the first call of ixr. But due to the error and my command "../fasm forsr.asm forsr -m 60000 -s fors.fas > forsr.txt && ../flist fors.fas forsr.lst" I have to copy the output from from tty:
tjp0 0000 tcpn 0002 tcpd 0004 tcpc 0006 tgpc 0008 tcpx 000A tgpx 000C txct 000E tapc 0010 trch 0012 trcw 0014 trwc 0016 trxc 0018 taxp 001A pnop 0020 tsel 0022 pxct 0024 pbpt 0026 p4lh 0028 tabc 002A tabh 002C pret 002E pdon 0030 tli$ 0032 tlic 0034 tlih 0036 tfyc 0038 tliw 003A prpw 003C tqhl 003E tlol 0040 tlop 0042 tjmp 0044 tjtz 0046 tdjn 0048 prih 004A p2ad 004C pric 004E pinc 0050 pirh 0052 prnh 0054 pirw 0056 ...(part of my preliminary table, see tjtz 0046)
forsr.asm [1431]:
x pqdp w pxct a t pret
forsr.inc [324] x [14]:
ixr rtjmp
forsr.inc [324] irps [11]:
ixr rtjmp
forsr.inc [400] ixr [1]:
load xd word from refs:xa
processed: load xd word from refs:rtjmp
error: value out of range.(the end of output)
I understand why this happens (tjmp is not yet defined at this time) but as I understand the resolving policy of fasm, it should take note of this fact and resume later. (As we humans know, the action of ixr does not even need new memory space, the word to be incremented is at refs:0044h Smile.
For completeness: line 1431 of forsr.asm is "x pqdp w pxct a t pret". ixr is called because of token "a".
As reported, I hoped that "assert 0" would have made fasm to continue, but maybe there is some other measure.
Thank you.
PS. I am on a public internet service which will shut down soon. I will replace the zip with a shorter version as soon as possible.


Last edited by pipifax on 10 Jul 2025, 19:32; edited 1 time in total
Post 09 Jul 2025, 20:35
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4260
Location: vpcmpistri
bitRAKE 09 Jul 2025, 22:10
pipifax wrote:
I understand why this happens (tjzp is not yet defined at this time) but as I understand the resolving policy of fasm, it should take note of this fact and resume later. (As we humans know, the action of ixr does not even need new memory space, the word to be incremented is at refs:0046h Smile.
Perhaps I am incorrect, but I cannot find an example that automatically expands an address space. Nor does the code present expand the "refs" address space beyond the present zero size.

So, let us try another solution:

First, I uncomment all the "ixr" use.

Next, I modify "refs" address space:
Code:
virtual at 0
refs::
 rb 2+sizeof.refs
end virtual    
Finally, we calculate needed size of "refs", at the end of "forsr.asm":
Code:
irpv n,name { common temp = 0
 forward
 if r#n > temp
  temp = r#n
 end if
} sizeof.refs = temp    
... and you are correct fasm will resolve all the delayed calculations.

Yet, without expanding the address space, fasm does not, afaik. Perhaps, you are requesting a feature? Arbitrarily sized address spaces would introduce more problems than it would solve, imho.

Therefore, I have provided both a static and dynamic solution to the problem you've stated in your initial post. Your assumptions regarding the "resolving policy of fasm" with regard to address spaces appears to be incorrect.

"assert 0" stops the assembler, as the logical expression is false. I cannot find a reference in the manual to a use of "assert 0" to solve some problem. What are you referring to?
Post 09 Jul 2025, 22:10
View user's profile Send private message Visit poster's website Reply with quote
pipifax



Joined: 04 Aug 2023
Posts: 5
pipifax 10 Jul 2025, 20:44
bitRAKE:
I cannot see wether you REPLACED my code(irpv where names and r#n values are printed - in the hope that all gets resolved) or if you ADDED your code 1st(redefinition of refs with size+=2) and 2nd(irpv where the maximum temp of all r#n values is calculated and refs resized). Do you know the value of temp for comparison? And, if you had no errors inspite of some or all ixr active, I would have liked to see the values of the elements.
Anyhow, I will try the same with your 2nd code in IN PLACE OF mine. refs has 2 unused elements at offsets 1ch and 1eh and some 10 at the and.
I will omit resizing with temp as
- this may invalidate refs and all elements' values
- if you agree that the temp is the greatest offset, then the size must be temp+2 because the smallest offset is 0. This imho would exclude the last USED element.
I understand, that the static and dynamic solution are what i called your 1st and 2nd code.
"assert 0" is from 1.72, the version I use because of my listing generator, which uses this version.
I will report my results.
Thank you
Post 10 Jul 2025, 20:44
View user's profile Send private message Reply with quote
pipifax



Joined: 04 Aug 2023
Posts: 5
pipifax 19 Jul 2025, 20:27
; This project aims to build a binary FORS(R) capable to execute or compile
;text input from keyboard or file. Typical commands for the build are shown
;in lines 6 to 13 of .asm files.
; As an aid for the builder to include /leave out parts of the source file,
;I wanted to add a reference table to the compilation output, showing how
;often each function has been called by any other. This reftable is the
;very topic of this post.
[code]virtual at 0
refs::
dw 0 dup 16+128+400
end virtual
rnxt=0[\code]
; This array size reflects the current size of FORS. A theoretical limit
;would allow for 2^15-1 function-calls=refs, so entries would need only
;15 bits for ref-count, and the msbit can be used to flag the functions'
;invisibility (to users of FORS).
; FORS functions (during build process) are FASM symbols of 4 characters.
;These may be referred to as the assembly or meta name, as parameter 'nam'.
;When a function 'myfc' is defined, its array location will be named 'rmyfc'.
;There are 2 macros, P and H, for function definitions. P uses assembly code,
;these functions do not make references and are placed before all H-made
;ones, which are mere lists of tokens, most of these references to P- and
;other H-functions.
; The number of P-functions is currently limited to 14+2spare+128, while the
;set of H-type ones is, assisted by reftable, managed by the builder.
[code]macro h nam,..{;here restricted to reftable functionality.
rloc nam;if r#nam is undefined, allocates next free array location
a#nam: name equ nam
nam=expression($)
}[\code]
; If myfc is to be invisible (for users), add 8000h to REFS:RMYFC.
; If myfc is being referred to, increment REFS:RMYFC. This is often due
;before myfc has been defined. In the first version rmyfc was defined
;inside P or H, which was a too heavy load for fasm's resolving policy.
; This second version will define rmyfc (that is allocate an element of
;REFS) immediately at the first access by RLOC which is called in RINC
;(the former IXR), P and H (all in file forsr.inc):
[code]macro rloc nam {;allocate r#nam if undefined, prints for debug
display 'R',`nam,32
if ~defined r#nam ;prevents multiple definition
p4 rnxt
r#nam=rnxt
rnxt=rnxt+2
end if
}[\code]
; When a functions is referred to before being defined, its ref
;location is defined immediately by RINC !
[code]macro rinc nam,inc=1 {;increment refs:r#nam, prints for debug
rloc nam ;replaces ixr
load ref word from refs:r#nam
ref=ref+inc
p4 ref
store word ref at refs:r#nam
; store word ref+inc at refs:r#nam
}[\code]
; These new macros, imho are correct and also general, so they can
;be called at any point of definition and referenc respectively,
;and need not care for specific dependencies inside fors.
;I installed fors v1.73.30 and could not find any differences in
;the binary or listing files .lst (from symbol file) and .txt
;accumulated output. As I (with reason) normally work in tty:
../fasm forsr.asm forsr -m 60000 -s fors.fas > forsr.txt && ../flist fors.fas forsr.lst
; Sometimes, there is a problem in case of fasm error: the output
;scrolls down, most valuable information is gone, because forsr.txt
;ends up as vline="flat assembler version vvvv".
;IS THERE A KNOWN DEFINITION OF SOMETIMES?
;IS IT LINUX OR FASM WHO CLEARS EVERYTHING ELSE ACCUMULATED BY ">"?
;WHAT CAN I DO TO PREVENT THIS?? (">>" ADDS only 1 more vline)
----------------------------------------------------------------
Removed calls of RLOC and RINC -> compiles without errors
Added "rloc hfrd"
added "p4 rhfrd" -> no errors, printed 0000 ok
Added
[code]irpv n,name
if defined r#n
display `n,32
p4 r#n
end if }[\code]
forsr.asm [2263]
if defined r#n
error: unexpected characters.
Removed "if defined" "end if" -> .. display `n,32 error: unexpected characters
Removed "`" -> .. display n,32 error: unexpected characters
;3 CASES OF UNEXPECTED CHARACTERS! Wouldn't it help to see these characters
;in context. This is not yet a feature request. Removed irpv..}
Added, after "h nmyl ..", "rloc nmyl" -> error: code could not be generated
;I somehow suspect "if ~defined r#n". Now, as if fasm were offended,
;whatever I did, it insisted on "error: code could not be generated".
AFAIK, THERE IS NO HIDDEN MEMORY OF PREVIOUS RUNS!?
----------------------------------------------------------------
; Thinking about "code could not be generated": Without any knowledge of
;fasm's processing or source details details, but with programmer's manual
;chapters on constants and variables, multiple passes ( if ~defined alpha..).
;Suspecting RLOC, here is no fixed-name "alpha", but an object named r#nam,
;which, combined with ~defined, is deemed impossible.
;So, if you remember a working macro equivalent to RLOC
macro mmm nnn.. { .. if ~defined rrr#nnn .. rrr#nnn=val .. endif }
;please post it with all elements to show how equivalence is achieved.
;Also, what does "error: code could not be generated" exactly mean?
----------------------------------------------------------------
; Just do show what was possible as a single 'event', this copy from tty:
[list]../fasm forsr.asm forsr -m 60000 -s fors.fas > forsr.txt && ../flist fors.fas forsr.lst
forsr.asm [878]:
h soae,,tjp0,,,soae;ai.co ae--[co]
forsr.inc [217] h [46]:
rinc t <-- t is tjp0
forsr.inc [408] rinc [3]:
load ref word from refs:r#nam <-- no error!
processed: load ref word from refs:rtjp0 <-- as it should be!
error: undefined symbol 'rtjp0'. <-- looks like "rloc tjp0" had failed[\list]
----------------------------------------------------------------
; Attempted to avoid as much of these dangerous "defined" "r#n" and
;"load ref word at refs:r#n" I took advantage of forsr's properties:
;1. P-made functions make no references and are all defined befor H-made ones.
;2. a#nam in (P and) H being defined is practically equivalent to using r#nam.
;which allow to (regarding ref operations)
;1. change P back to 'version1' state, and (param t is always P-made)
;2. change "rinc t" in H to directly: load at..+=1..store from/at refs:r#t.
;3. "if ~defined r#nam" in RLOC (in H and RINC) changed to "if..a#nam".
;4. All RINC calls (in X) were reenabled -> error: out of memory (ok -m 64000)
; Added multiple printouts (RTBL and reduced variants), all caused
;"error: unexpected characters" on "if defined.." "display `n..) or
;"load ref word from refs:r#n" <-- error:value out of range.
;Removed printout, added P4 for RTJP0,ref(RTJP0),RTJMP,ref(RTJP0),RPLR8,RSOAE
; Compile ended at change2 of SOAE with error like 2 lines above.
;But on tty (end of) full! output (as always file forsr.txt = vline) and P$=
;0000 0000 0044 0000 011E none, showing that change2 failed, RLOC (the 1 for soea)
;failed or was postponed. BUT disregarding thes effects, there was a FULL output
;since many retries. Back to error:value out of range on load and store!
[list]...
nmyl nmyl 8F880000 003ECE6D 0800171E MYL/ `
* h$fs=5288
ntop 0000---- 08001748
mbot C681---- 08001758
mtop 0070---- 080017C8
fbot D681---- 080017D8
ftop 1940---- 08003118
wbot CE81---- 08003128
wtop 0000---- 08003128
odd pto 0054 0003 tbt tbl iip nop 08000100 08000180 08000200 08000258
=0
rs0 bti bfs ps0 bfi 08000100 08003640 080036A3 080037FC 08003800
amem etxt umem shdm emem 0800173C 08003130 000005C0 00000400 08004000
abti axpp aoi0 abtb rnxt<688=8b0h 08000906 08000928 08001468 080014C2 00000120
0000 0000 0044 0000 011E
forsr.asm [877]:
h soae,,tjp0,,,soae;ai.co ae--[co]
forsr.inc [221] h [47]:
load ref word from refs:r#t
processed: load ref word from refs:rtjp0
error: value out of range.[\list]
; Forgotten question: What can I write into .asm file to stop assembly
;at this point without generating an error (because of 'stop')?
;I somehow managed to replace my original first post, and perhaps renewed
;the .zip archive - I hope this will do as "Load and Store Problems v2"


Description: See message body.
Download
Filename: forsr.zip
Filesize: 105.48 KB
Downloaded: 35 Time(s)

Post 19 Jul 2025, 20:27
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.