flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
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!
Last edited by pipifax on 08 Jul 2025, 20:11; edited 1 time in total |
|||||||||||
![]() |
|
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 |
|||
![]() |
|
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. |
|||
![]() |
|
bitRAKE 09 Jul 2025, 02:29
pipifax wrote:
pipifax wrote: So my question is: Code: virtual at 0 as 'refs' refs:: dw 16 dup 0 dw 128 dup 0 dw 400 dup 0 sizeof.refs = $ end virtual 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 } 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. |
|||
![]() |
|
revolution 09 Jul 2025, 20:28
pipifax wrote: revolution: |
|||
![]() |
|
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 ![]() 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 |
|||
![]() |
|
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 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 Code: irpv n,name { common temp = 0 forward if r#n > temp temp = r#n end if } sizeof.refs = temp 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? |
|||
![]() |
|
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 |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.