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: 4
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: 16 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: 20700
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: 4259
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: 4
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: 4259
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: 20700
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: 4
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: 4259
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: 4
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
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.