flat assembler
Message board for the users of flat assembler.

Index > Main > Address space offsets with virtual

Author
Thread Post new topic Reply to topic
gmg1812



Joined: 15 Aug 2014
Posts: 13
Location: Northern New York
gmg1812
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.


Description: Possible bug in "virtual"
Download
Filename: testdup.ASM
Filesize: 880 Bytes
Downloaded: 165 Time(s)

Post 09 Sep 2014, 21:05
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17249
Location: In your JS exploiting you and your system
revolution
You need to address the bytes from the offset within the addressing space.
Code:
virtual at 0x55555
        Symbol_Characters:: db 0
end virtual

load a byte from Symbol_Characters:0x55555      ;<---- load the addressed byte
load b byte from Symbol_Characters:0            ;<---- value out of range
    
Post 09 Sep 2014, 22:49
View user's profile Send private message Visit poster's website Reply with quote
gmg1812



Joined: 15 Aug 2014
Posts: 13
Location: Northern New York
gmg1812
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.


Description: Listing file
Download
Filename: testdup.txt
Filesize: 1.54 KB
Downloaded: 159 Time(s)

Post 10 Sep 2014, 02:08
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17249
Location: In your JS exploiting you and your system
revolution
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    
Post 10 Sep 2014, 02:34
View user's profile Send private message Visit poster's website Reply with quote
gmg1812



Joined: 15 Aug 2014
Posts: 13
Location: Northern New York
gmg1812
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
Post 10 Sep 2014, 03:09
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17249
Location: In your JS exploiting you and your system
revolution
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
Post 10 Sep 2014, 03:28
View user's profile Send private message Visit poster's website Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
If you have C/C++ background think of it as a cast.
Post 10 Sep 2014, 04:32
View user's profile Send private message Reply with quote
gmg1812



Joined: 15 Aug 2014
Posts: 13
Location: Northern New York
gmg1812
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
Post 10 Sep 2014, 12:50
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1408
Location: Toronto, Canada
AsmGuru62
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.
Post 10 Sep 2014, 14:45
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17249
Location: In your JS exploiting you and your system
revolution
gmg1812 wrote:
Or am I missing something here?
I think you are mixing global labels with local labels.

Global:
Code:
virtual at edi
 rr dd ?
end virtual
mov eax,[rr] ;uses edi    
Local:
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    
Post 10 Sep 2014, 21:44
View user's profile Send private message Visit poster's website 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-2020, Tomasz Grysztar.

Powered by rwasa.