flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > Symbols assignment bug ?

Author
Thread Post new topic Reply to topic
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 25 Jun 2007, 14:31
Consider this small program:

Code:
macro SECTION x* {
if BSSspace = 0
        BSSspace = $
        end virtual
end if
if x eq .bss
       virtual at BSSspace
 BSSspace = 0
else if ~ (x eq .text)
      display 'Invalid section'
end if
}

BSSspace = ProgramEnd

SECTION .bss
MyData      rw 1

SECTION .text
mov        [MyData], 7
ret

ProgramEnd:
    


Macro SECTION reflects Nasm behaviour, is used to put uninitialized data at the end of the program. It uses BSSspace to signal when we are inside a virtual block (BSSspace = 0) or outside, in this case BSSspace holds the current free location.
If you try to compile it won't, because at the first macro expansion Fasm thinks that BSSspace is 0 and places an End Virtual. How can BSSspace be 0 if we just declared it equal to ProgramEnd (which is of course not 0)? It seems an internal bug: on first pass, when Fasm doesn't know ProgramEnd value yet, temporarily sets BSSspace to 0 while it should set it to <nil>, Null, <uninitialized>, Empty or what your imagination tells you, but not to a particular value.
Being things like that, there is an easy workaround: use -1 instead of 0 and program compiles fine. Anyway I think this problem should be noticed.
Post 25 Jun 2007, 14:31
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 25 Jun 2007, 14:50
I can't find in the documentation this but the author told once in the forum that the initial predicted value of labels is 0. http://flatassembler.net/docs.php?article=manual#2.2.6 Here talks about multiple passes but it doesn't mention about the initial zero value (or I'm too blind).

Note also that if you change "if BSSspace = 0 " with "if ProgramEnd = 0" you get the same error.
Post 25 Jun 2007, 14:50
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 25 Jun 2007, 15:12
you are right, this is example that FASM can't solve. But i am not sure if there is another way.

During first pass FASM quesses value of symbol to be 0, so conditional block is assembled. In second pass FASM would found it mispredicted this condition, and wouldn't assemble conditional block. But unfortunately, it never gets to second pass, because there is assembing error in first pass (unmatched "end virtual").

For your case, it's a really bad idea to use same variable for two purposes, both detecting whether we are in .bss section, and holding address. Make another variable that marks if code is in BSS section.
Post 25 Jun 2007, 15:12
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 28 Jun 2007, 15:34
I'm not using that code, in fact it is a-bit-constructed example just to show the problem; it's not important at all what that fragment does or to make it work, I only wanted to submit a suggestion based on two observations:
1) The initial guess makes little sense: a label defined with : will never be 0 unless you specify ORG 0 and this is the first label of the program;
2) What is really important, Fasm aborts compilation basing on that guess which is wrong
Since this behaviour is not documented (anymore, according to LocoDelAssembly) - in the manual I hadn't found anything about that - someone might not immediately understand what's going on, should he/she find himself in such a situation.
This doesn't throw anything bad against FASM: it works very well and these examples are rare in practice when good programming styles are used; in these cases there are easy workarounds, as the one I proposed.
My suggestion is: introduce a state of <undefined> for labels, which doesn't stop compilation because of wrong assumptions.
Post 28 Jun 2007, 15:34
View user's profile Send private message Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 21 Oct 2007, 09:23
Here is another, more important IMHO, example:

if t1 < t2
rb t2
else
rb t1
end if
t1=100
t2=200

This will assemble to ZERO bytes! Note that if you replace rb with db it works correctly.
The same is for

rb temp

len=0

if len<2
len=2
end if

temp=len

I think this issue should be fixed.
Post 21 Oct 2007, 09:23
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 21 Oct 2007, 15:01
pfranz, rb does not output any byte in dest file, just reserve the address space.

Try for example this and you will see that it will get a much bigger file:
Code:
if t1 < t2
  rb t2
else 
  rb t1
end if 
t1=100
t2=200

db 0 ; Thanks to this byte fasm now needs to pad the RBs above with zeros    

201 bytes.

Also note that in others formats like PE happens the same but the section's virtual size will be bigger than its raw size.
Post 21 Oct 2007, 15:01
View user's profile Send private message Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 23 Oct 2007, 15:41
Yes, thank you, it was a silly mistake; in fact I tried what you said before you posted it, when I remembered that FASM doesn't reserve the space when there is no data after it. Ooops...
Post 23 Oct 2007, 15:41
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.