flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
gmg1812 09 Sep 2014, 21:05
Mr. Grysztar,
First my congratulations on an excellent pievce of work. Having been writing code in assembly language on numerous computer systems since 1964, your effort ranks with the best. However, as the attached file demonstrates, I believe I have found a bug. While delving into your source code, I decided to see if I could create your "characters" table entirely in the assembler, eliminating the generation code (in both places). I was successful, but while doing so I discovered what appears to be a bug with "virtual." In the attached code, if you assemble it as-is, the first "load" works while the second fails with a "Value out of range" error. Adding "at 0" to the second "virtual" and it assembles correctly. Adding "at 0" to the first "virtual" and leaving the second alone and the error persists. I have not (yet) delved enough into your assembler's source to see if this is a real bug or if there is something in the language specs I'm overlooking, but I thought I'd pass this along just in case. If I'm overlooking a rule, please let me know what it is. If it is a bug, and you decide to fix it, would you be so kind as to let me know the changes necessary for FASM 1.71.21? Thanks. Gary M. Gibson, Ph.D.
|
|||||||||||
![]() |
|
gmg1812 10 Sep 2014, 02:08
I see your point, but I think there is still a consistency problem.
Consider the attached listing. The first load/store fails & demonstrates your point. The stores went into west hyperspace. The second load/store (which works) seems to ignore the reference to "Symbol Characters" but bases the byte it grabs ONLY on the specified byte offset. The third load/store makes matters worse, as it is now clear you can reference any variable in a virtual for a load so long as the byte offset is correct. What appears to be wrong here is you would expect that all byte offsets would be relative to the data name (variable, what have you) specified. In case two, you should not have to worry about what the virtual offset is to Symbol_Characters. The internal "location counter" within virtual should take care of that. In other words, offsets to variables defined within a virtual should be relative to the start of that variable, just as you would expect outside the virtual, whether coded witha "+" or a ":". Incidentally, a reference to the location counter ($) in a virtual also doesn't work quite as I expected. virtual L1 db 1,2,3,4,5 L1L = $-L1 <--- fails here, works great outside the virtual end virtual BTW, your forward/common/reverse in a macro was a brilliant idea. So simple yet so powerful. Gary M. Gibson, Ph.D.
|
|||||||||||
![]() |
|
revolution 10 Sep 2014, 02:34
Address space labels point to the start of the virtual block. Normal labels defined within the block give the offset.
Code: virtual at 0 AddressSpace:: NormalLabel: db '0' AnotherLabel: db '1' end virtual load a byte from AddressSpace:NormalLabel load b byte from AddressSpace:AnotherLabel display a,b |
|||
![]() |
|
gmg1812 10 Sep 2014, 03:09
Aha! Thanks.
The example on the bottom of page 79 in your Programmers Manual was what confused me. I now see that you don't need more than one "::" label in a virtual, or if you do, they're all the same. I still can't figure out how to get "rid" of a virtual once it's there. Suppose you have rr1 MYREC ; a struct mov esi,rr1 virtual at esi rr MYREC end virtual then you reference things like [rr.field1] and all's well. but later, you change the contents of esi and still further, you make a mistake and code [rr.field1],eax when you should have written [rr1.field1],eax That bug can be really hard to find! Is there a way to make a virtual register association "go away"? virtual at esi end virtual Doesn't do it, as a later ref to [rr.field1] Is accepted without error. ???? Gary |
|||
![]() |
|
revolution 10 Sep 2014, 03:28
The rr label will have the base esi as part of the definition of rr. The virtual block does not alter the usage of esi, it only associates esi with each usage rr.
Perhaps you can name your label rr.esi to remind you that when using rr it will implicitly use esi also. Last edited by revolution on 10 Sep 2014, 04:39; edited 1 time in total |
|||
![]() |
|
typedef 10 Sep 2014, 04:32
If you have C/C++ background think of it as a cast.
|
|||
![]() |
|
gmg1812 10 Sep 2014, 12:50
I agree, my programming bug could have been resolved by a better definition of rr as rr.esi, but, as the whole purpose of virtual seems to be to simplify references to data, what seems to be missing here is the concept of scope of association. The way FASM works now, once rr is associated with esi there is no easy way to eliminate it. Names defined within a virtual are global
to the assembly. If I wish to associate (or "base") esi on a reference to rr1 MYREC as before, like: virtual at esi .rr MYREC end virtual all's well. If I later want to change to use ebx, and try to write virtual at ebx .rr MYREC end virtual FASM reports .rr is already defined as both .rr's exist in the same namespace. However, changing the second virtual to virtual xx: .rr equ q end virtual assembles without error and mov eax,.rr uses the second definition of .rr. To catch the error I noted earlier, changing the definition of .rr in the second virtual to ,rr equ 'acdefghi' will generate an "out of range" error if referenced as mov eax,.rr This, I admit, allows one to "redefine" or "get rid of" an unwanted virtual association, but it seems a messy way to do it. Or am I missing something here? Gary |
|||
![]() |
|
AsmGuru62 10 Sep 2014, 14:45
Or you can what I do:
Code: virtual at 0 MYREC: .member1 dd ? .member2 dd ? .member3 dd ? .size=$ end virtual Then you can load any register with an address to MYREC and use an offset: Code: invoke GetProcessHeap mov ebx, eax ; ; Allocate MYREC instance #1 ; invoke HeapAlloc, ebx, HEAP_NO_SERIALIZE, MYREC.size mov edi, eax ; ; Allocate MYREC instance #2 ; invoke HeapAlloc, ebx, HEAP_NO_SERIALIZE, MYREC.size mov esi, eax ; ; Now put some values into these instances ; mov [edi + MYREC.member2], 8086h mov [esi + MYREC.member1], 8087h ; ; Load the address of MYREC #1 member3 into EBP ; lea ebp, [edi + MYREC.member3] I find it more natural to read - code resembles the debugger listing. |
|||
![]() |
|
revolution 10 Sep 2014, 21:44
gmg1812 wrote: Or am I missing something here? Global: Code: virtual at edi rr dd ? end virtual mov eax,[rr] ;uses edi Code: proc1: virtual at esi .rr dd ? end virtual mov eax,[.rr] ;uses esi proc2: virtual at ebx .rr dd ? end virtual mov eax,[.rr] ;uses ebx mov eax,[proc1.rr] ;uses esi mov eax,[proc2.rr] ;uses ebx |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.