flat assembler
Message board for the users of flat assembler.

Index > Main > [fasmg] "display" is executed even just after an "err"

Author
Thread Post new topic Reply to topic
VEG



Joined: 06 Feb 2013
Posts: 80
VEG 05 May 2017, 19:22
I've encountered a very strange behavior of display/err directives.
Code:
macro call1 val

        display 'detailed info before an assert 0',13,10
        assert 0

end macro

macro call2 val

        display 'detailed info before an error',13,10
        err 'out of range'

end macro

call1
call1
call2
call2    
Code:
d:\Projects\NFS\nfs3_patch\incasm>fasmg test.asm test.bin
flat assembler  version g.hs4p0
detailed info before an assert 0
detailed info before an assert 0
detailed info before an error
detailed info before an error

test.asm [15]:
        call1
macro call1 [3]:
        assert 0
Processed: assert 0
Error: assertion failed.

d:\Projects\NFS\nfs3_patch\incasm>    
How can it be possible? The first assert prevented assembling, but actually it is not: all display directives were executed.

FASMG manual doesn't say anything about such strange behavior:
Quote:
The "display" instruction causes a sequence of bytes to be written into standard output, next to the messages generated by the assembler. It should be followed by strings or numeric values of single bytes, separated with commas.
The "err" instruction signalizes an error in the assembly process, with a custom message specified by its argument. It allows the same kind of arguments as the "display" directive.
It would be nice what really these directives do in FASMG. It seems that behavior was changed too much in comparison to FASM1.

I'm using it for displaying detailed information about errors (with numbers like offsets to explain an exact reason of an error, it is not just a string, so I have to use display before an err directive).
Post 05 May 2017, 19:22
View user's profile Send private message Visit poster's website Reply with quote
VEG



Joined: 06 Feb 2013
Posts: 80
VEG 05 May 2017, 19:27
Much simpler example which explains the problem:
Code:
display 'before the error1',13,10
err 'error1'
display 'before the error2',13,10
err 'error2'
display 'after everything',13,10    
The result of execution:
Code:
flat assembler  version g.hs4p0
before the error1
before the error2
after everything

test.asm [2]
Custom error: error1.    
Post 05 May 2017, 19:27
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 05 May 2017, 19:42
The documentation of ERR is perhaps not clear enough, this directive simply registers an error to be signaled but this does not alter the flow of the assembly. This is because almost all errors that may happen during the assembly with fasmg are potentially "recoverable" - which means that they may vanish in the consecutive passes of the resolving process (the only exception, a "fatal" error, is when assembler runs out of memory). If you need to use DISPLAY to provide additional information related to an error, you have to put it under the same condition as the ERR directive.

VEG wrote:
How can it be possible? The first assert prevented assembling, but actually it is not: all display directives were executed.
Actually, with ASSERT this is nothing new even with relation to fasm 1. In fasm 1 the ASSERT directive also registered a recoverable error and did not terminate the assembly.
Post 05 May 2017, 19:42
View user's profile Send private message Visit poster's website Reply with quote
VEG



Joined: 06 Feb 2013
Posts: 80
VEG 05 May 2017, 20:07
Quote:
If you need to use DISPLAY to provide additional information related to an error, you have to put it under the same condition as the ERR directive.
It doesn't change anything.
Code:
macro call1 val

        if val > 0x1000
                display 'detailed info about an error',13,10
                err "can't be more than 0x1000"
        else
                dw val
        end if

end macro

call1 0x2000
call1 0x2000    
Code:
flat assembler  version g.hs4p0
detailed info about an error
detailed info about an error

test.asm [12]:
        call1 0x2000
macro call1 [4]
Custom error: can't be more than 0x1000.    

Quote:
This is because almost all errors that may happen during the assembly with fasmg are potentially "recoverable" - which means that they may vanish in the consecutive passes of the resolving process (the only exception, a "fatal" error, is when assembler runs out of memory).
Maybe it is better at least to hide all messages from the "display" directive after an "err"?
Post 05 May 2017, 20:07
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 05 May 2017, 20:09
VEG wrote:
Maybe it is better at least to hide all messages from the "display" directive after an "err"?
It was intentional both in fasm 1 and in fasmg to dump all the messages from DISPLAY even if an error happened, for debugging purposes. Though perhaps it makes sense to turn it into an option switchable from command line.
Post 05 May 2017, 20:09
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 05 May 2017, 20:13
VEG wrote:
Quote:
If you need to use DISPLAY to provide additional information related to an error, you have to put it under the same condition as the ERR directive.
It doesn't change anything.
Code:
macro call1 val

        if val > 0x1000
                display 'detailed info about an error',13,10
                err "can't be more than 0x1000"
        else
                dw val
        end if

end macro

call1 0x2000
call1 0x2000    
Code:
flat assembler  version g.hs4p0
detailed info about an error
detailed info about an error

test.asm [12]:
        call1 0x2000
macro call1 [4]
Custom error: can't be more than 0x1000.    
If you run fasmg with an option like "-e100" you may better understand what is happening here:
Code:
flat assembler  version g.hs4p0
detailed info about an error
detailed info about an error

a.asm [12]:
        call1 0x2000
macro call1 [4]
Custom error: can't be more than 0x1000.
a.asm [13]:
        call1 0x2000
macro call1 [4]
Custom error: can't be more than 0x1000.    
The problem that you have is that the messages from DISPLAY are shown separately from the error messages (and note that messages from DISPLAY go to stdout while the error messages go to stderr). You may use variables like __FILE__ and __LINE__ to show additional information to connect the information from DISPLAY with a line in source. Or, alternatively, you can construct a multi-line string to pass to the ERR directive and put everything into stderr this way.
Post 05 May 2017, 20:13
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 05 May 2017, 20:22
Here's an example how you can construct a multi-line error message:
Code:
macro call1 val
        if val > 0x1000
                local errmsg
                virtual at 0
                        db "can't be more than 0x1000",13,10
                        db 'detailed info about an error'
                        load errmsg:$ from 0
                end virtual
                err errmsg
        else 
                dw val 
        end if 
end macro 

call1 0x2000 
call1 0x2000    
Code:
>fasmg test.asm nul -e100
flat assembler  version g.hs4p0
a.asm [15]:
        call1 0x2000
macro call1 [8]
Custom error: can't be more than 0x1000
detailed info about an error.
a.asm [16]:
        call1 0x2000
macro call1 [8]
Custom error: can't be more than 0x1000
detailed info about an error.    
Post 05 May 2017, 20:22
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 05 May 2017, 20:26
And the second example is how you can do it with DISPLAY only if for some reason you'd need this information in STDOUT instead of STDERR:
Code:
macro call1 val
        if val > 0x1000
                local errmsg
                virtual at 0
                        db "error in ",__FILE__
                        repeat 1, n:__LINE__
                                db ", line number ",`n,":",13,10
                        end repeat
                        db "can't be more than 0x1000",13,10
                        db 'detailed info about an error',13,10
                        load errmsg:$ from 0
                end virtual
                display errmsg
        else 
                dw val 
        end if 
end macro 

call1 0x2000 
call1 0x2000    
Post 05 May 2017, 20:26
View user's profile Send private message Visit poster's website Reply with quote
VEG



Joined: 06 Feb 2013
Posts: 80
VEG 05 May 2017, 20:29
Yeah, it seems that it is better to avoid the "display" directive for information about errors Smile Maybe "display" will be useful for displaying of some statistics.

Thank you for the example.
Post 05 May 2017, 20:29
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.