flat assembler
Message board for the users of flat assembler.

Index > Main > FASMG and namespace

Goto page 1, 2, 3, 4  Next
Author
Thread Post new topic Reply to topic
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 12:08
Hello, I have a question about fasmg, I actually migrate my project to fasmg, because they are a lot of new features I love, and I have question about namespace.

I give you an example:
Code:
namespace Some

    namespace Thing
        value = 0
    end namespace

    namespace ThingElse
        var = Thing.value
    end namespace

end namespace
    


My question is, how can I access to the first namespace in my ThingElse namespace, because if I assemble this code, I have an error
Post 12 Jan 2021, 12:08
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 12 Jan 2021, 12:26
You have not defined a symbol named "Thing" anywhere, therefore when you refer to it, the assembler defaults to "case sensitive symbol in current namespace". For example, when you are inside "Some.ThingElse" namespace, by writing "Thing" you refer to the symbol "Some.ThingElse.Thing", and therefore "Thing.value" is "Some.ThingElse.Thing.value". If you are using a sufficiently recent version of fasmg, you can see this reflected in the error message:
Code:
flat assembler  version g.j6a0
test.asm [8]:
        var = Thing.value
Processed: var = Thing.value
Error: symbol 'Some.ThingElse.Thing.value' is undefined or out of scope.    
This default fall-back (when symbol is undefined) is equivalent to the following situation:
Code:
namespace Some

    namespace Thing
        value = 0               ; defines Some.Thing.value
    end namespace

    namespace ThingElse
        Thing:
        var = Thing.value       ; accesses Some.ThingElse.Thing.value
    end namespace

end namespace    
However, if you do not define "Thing" localy and define it at a higher level, then the name may refer to a place elsewhere in the hierarchy:
Code:
namespace Some

    Thing:
    namespace Thing
        value = 0               ; defines Some.Thing.value
    end namespace

    namespace ThingElse
        var = Thing.value       ; accesses Some.Thing.value
    end namespace

end namespace    
Code:
Thing:
namespace Some

    namespace Thing
        value = 0               ; defines Thing.value
    end namespace

    namespace ThingElse
        var = Thing.value       ; accesses Thing.value
    end namespace

end namespace    
The NAMESPACE command does not define anything by itself, it only switches context to one associated with a given symbol (perhaps it should have been named like IN_NAMESPACE to emphasize that). In general I'd highly recommend always using NAMESPACE anchored to a symbol that is well-defined. You could even enforce this by using some kind of a simple wrapper for NAMESPACE command:
Code:
calminstruction namespace? path*
        local cmd
        check defined path
        jyes proceed
        arrange cmd, =err 'namespace refers to an undefined symbol'
        assemble cmd
    proceed:
        arrange cmd, =namespace path
        assemble cmd
end calminstruction    
Post 12 Jan 2021, 12:26
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20300
Location: In your JS exploiting you and your system
revolution 12 Jan 2021, 13:04
So does that mean the OP can also change just one line like this?
Code:
;...
        var = Some.Thing.value
;...    
Post 12 Jan 2021, 13:04
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 12 Jan 2021, 13:44
revolution wrote:
So does that mean the OP can also change just one line like this?
Code:
;...
        var = Some.Thing.value
;...    
No, because "Some" is also not defined anywhere and would default to a local symbol (this would end up referring to "Some.ThingElse.Some.Thing.value").
But it would work if "Some" was defined as a global label.

Another way to look at it: if you took the text that is inside "namespace ThingElse" block and assembled it at a root level, it would behave the same way (accessing "Some.Thing.value" and "var" instead of "Some.ThingElse.Some.Thing.value" and "Some.ThingElse.var"). This allows for a reliable encapsulation and separation of assembly modules that may have originally been written in a global context, etc.
Post 12 Jan 2021, 13:44
View user's profile Send private message Visit poster's website Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 15:24
Before you reply, I understood, thanks you Very Happy

I have just one other question, during my migration, I encountered a last bit problem, just with PE64 EFI format.

I just copied the includes required files into my project to use EFI PE format with fasmg (includes files in the fasmg archive), but when I try to assemble, I have this strange error:

Code:
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ fasmg BOOTX64.fasm 
flat assembler  version g.j5ii
BOOTX64.fasm [3]:
        format PE64 EFI
macro format?.PE64? [2]:
        PE.Settings.Machine = IMAGE_FILE_MACHINE_AMD64
Processed: PE.Settings.Machine = IMAGE_FILE_MACHINE_AMD64
Error: symbol 'IMAGE_FILE_MACHINE_AMD64' is undefined or out of scope.
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ fasmg BOOTX64.fasm 
flat assembler  version g.j5ii
BOOTX64.fasm [4]:
        format PE64 EFI
macro format?.PE64? [68]:
        include 'format/pe.inc'
Processed: include 'format/pe.inc'
Error: source file 'format/pe.inc' not found.    


You can see I try to include pe.inc to avoid the symbol no defined problem, but when I try to include this file, fasmg complain he don't exist....

Code:
include "include/format/pe.inc"
include "include/format/format.inc"

format PE64 EFI
entry Bootx64

include "Virtual/Virtual.fasm"

section '.text' code readable executable

include "Code/Code.fasm"

Bootx64:
Code.UEFI.Initialize

Code.UEFICall ConOut,SimpleTextOutputProtocol,ClearScreen,1, \
        InstancePointer

Code.UEFI.GetStatusCode [text1]
        
Code.UEFI.Call BootServices,BootServices,GetMemoryMap,5, \
        Address,[Data.UEFI.GetMemoryMap.MemoryMapSize]

Code.UEFI.GetStatusCode [text2]
        
mov rax,[Data.UEFI.GetMemoryMap.MemoryMapSize]
add qword [Data.UEFI.GetMemoryMap.MemoryMapSize],rax

Code.UEFI.Call BootServices,BootServices,AllocatePool,3, \
        Value,MemoryType.LoaderData, \
        Value,[Data.UEFI.GetMemoryMap.MemoryMapSize], \
        Address,[Data.UEFI.GetMemoryMap.MemoryMapAddress]

Code.UEFI.GetStatusCode [text3]

Code.UEFI.Call BootServices,BootServices,GetMemoryMap,5, \
        Address,[Data.UEFI.GetMemoryMap.MemoryMapSize], \
        Value,[Data.UEFI.GetMemoryMap.MemoryMapAddress], \
        Address,[Data.UEFI.GetMemoryMap.MapKey], \
        Address,[Data.UEFI.GetMemoryMap.DescriptorSize], \
        Address,[Data.UEFI.GetMemoryMap.DescriptorVersion]

Code.UEFI.GetStatusCode [text2]

Code.UEFI.Call ConOut,SimpleTextOutputProtocol,OutputString,2, \
        InstancePointer,0, \
        Address,[text4]
        
Code.UEFI.GetStatusCode [text4]

jmp $

section '.data' data readable writable

include "Data/Data.fasm"

text1: dw "UEFI ClearScreen:",0xD,0xA,0x0
text2: dw "UEFI GetMemoryMap:",0xD,0xA,0x0
text3: dw "UEFI AllocatePool:",0xD,0xA,0x0
text4: dw "UEFI OutputString:",0xD,0xA,0x0
    


The hierarchy :

Code:
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ ls
BOOTX64.fasm  Code  Data  include  Virtual
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ ls include/
80186.inc  80287.inc  80387.inc  8086.inc  ext     p5.inc  x64.inc
80286.inc  80386.inc  80486.inc  8087.inc  format  p6.inc
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ ls format
ls: cannot access 'format': No such file or directory
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ ls include/format
coff.inc  coffms.inc  elf32.inc  elf64.inc  elfexe.inc  format.inc  macho.inc  mz.inc  pe.inc
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $    
Post 12 Jan 2021, 15:24
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 12 Jan 2021, 17:22
Fulgurance wrote:
I just copied the includes required files into my project to use EFI PE format with fasmg (includes files in the fasmg archive), (...)
Please try the include set from the compatibility package instead, it should behave better.
Post 12 Jan 2021, 17:22
View user's profile Send private message Visit poster's website Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 17:37
Similar type of error, a problem with the path I think. I again copied the include directory and include the format.inc file, but I have this error:

Code:
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ fasmg BOOTX64.fasm 
flat assembler  version g.j5ii
BOOTX64.fasm [3] macro format?.PE64? [68] macro format?.include [1] include/format/pe.inc [296]:
        include 'cpu/8086.inc'
Processed: include 'cpu/8086.inc'
Error: source file 'cpu/8086.inc' not found.    


The beginning of my file:
Code:
include "include/format/format.inc"

format PE64 EFI
entry Bootx64    
Post 12 Jan 2021, 17:37
View user's profile Send private message Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 18:50
Tomasz, do you want I upload my project for you? To check
Post 12 Jan 2021, 18:50
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 12 Jan 2021, 19:09
You need to set up the INCLUDE variable pointing to the headers (see my video guide for example, although it is Windows-based).
Post 12 Jan 2021, 19:09
View user's profile Send private message Visit poster's website Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 19:15
Ah okay thanks you.

I have one other question, is it possible to do the same thing as namespace with LABEL, I want to do something like that:

Code:
Data:
    UEFI.Handle: dq ?

mov [Data.UEFI.Handle],0x0
    


This code don't work, but how can I do that? -> Data.UEFI.Handle

And about to set the variable INCLUDE, I seen your video, but I'm on Linux, I just set variable before call ? I always need to do that?
Post 12 Jan 2021, 19:15
View user's profile Send private message Reply with quote
Calanor



Joined: 19 Jul 2015
Posts: 45
Location: Sweden
Calanor 12 Jan 2021, 19:57
Fulgurance: Put the data lines in the relevant namespace block, like this:
Code:
Data:
namespace Data
    UEFI.Handle: dq ?
end namespace

mov QWORD[Data.UEFI.Handle],0x0
    

[Edit] Well, or just add a dot in front of "UEFI.Handle:".
Post 12 Jan 2021, 19:57
View user's profile Send private message Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 20:07
Oh okay... And namespace don't impact the label value ?
Post 12 Jan 2021, 20:07
View user's profile Send private message Reply with quote
Calanor



Joined: 19 Jul 2015
Posts: 45
Location: Sweden
Calanor 12 Jan 2021, 20:38
I'm not entirely sure that I follow you, but switching to the "Data" namespace won't affect the actual value of the label "Data". Bear in mind though that the name "Data" is used in a macro definition found in "pe.inc", just in case you happen to use that one.

On a related subject: Tomasz, is the above actually intended to clash with the macro in "pe.inc", where it's declared as case-insensitive? I got the impression that case-sensitive names are meant to take precedence over case-insensitive ones.
Post 12 Jan 2021, 20:38
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 12 Jan 2021, 20:41
Calanor wrote:
On a related subject: Tomasz, is the above actually intended to clash with the macro in "pe.inc", where it's declared as case-insensitive? I got the impression that case-sensitive names are meant to take precedence over case-insensitive ones.
There is an added layer of complexity because in this case you have a case-insensitive instruction, which then takes precedence, because "Data:" line is seen as calling said instruction. If there was a case-sensitive instruction called "Data" defined, it would take precedence over the case-insensitive one, but it is not the case here.

However, you can override it by using a modifier to force the identifier be recognized as expression-class instead of instruction-class:
Code:
?Data:    
Post 12 Jan 2021, 20:41
View user's profile Send private message Visit poster's website Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 21:36
Nice thanks for your complete replies !

Just one other question, I need to convert one of my macro, and I need to test if one of an argument isn't defined, how I can test that? (because I have optionals arguments)
Post 12 Jan 2021, 21:36
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 12 Jan 2021, 21:42
Fulgurance wrote:
Just one other question, I need to convert one of my macro, and I need to test if one of an argument isn't defined, how I can test that?
You can test it with MATCH, quite similarly to how you would do it in fasm 1:
Code:
match , arg
    display 'argument is empty'
end match    
Post 12 Jan 2021, 21:42
View user's profile Send private message Visit poster's website Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 21:48
Is it possible to write something like "not match" ? I want to do something when the parameters isn't used

Or perform match with nothing?
Post 12 Jan 2021, 21:48
View user's profile Send private message Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 21:52
Tomasz Grysztar wrote:
Fulgurance wrote:
Just one other question, I need to convert one of my macro, and I need to test if one of an argument isn't defined, how I can test that?
You can test it with MATCH, quite similarly to how you would do it in fasm 1:
Code:
match , arg
    display 'argument is empty'
end match    


Oh sorry, now I understand it's that
Post 12 Jan 2021, 21:52
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 12 Jan 2021, 21:54
Fulgurance wrote:
Is it possible to write something like "not match" ?
In fasmg MATCH allows ELSE, just like IF.
Post 12 Jan 2021, 21:54
View user's profile Send private message Visit poster's website Reply with quote
Fulgurance



Joined: 27 Nov 2017
Posts: 276
Fulgurance 12 Jan 2021, 22:22
Okay. Now I have other correction to do.

Anonyme label exist with fasmg ? Because when I try to assemble one of my macro, I have this error:
Code:
zohran@msi-gs73vr-6rf ~/Documents/Programmation/OS $ fasmg BOOTX64.fasm 
flat assembler  version g.j5ii
BOOTX64.fasm [18]:
        Code.UEFI.GetStatusCode [text1]
macro Code.UEFI.GetStatusCode [6] jne? [2] x86.parse_jump_operand [25] x86.parse_operand [38] (CALM)
Error: symbol '@f' is undefined or out of scope.    


I just thanks you again for your assembly, for me it's the most simple assembly language and with a lot of features, very nice work man
Post 12 Jan 2021, 22:22
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3, 4  Next

< 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.