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 |
|||
![]() |
|
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"
|
|||||||||||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.