flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > CALM asm macro

Author
Thread Post new topic Reply to topic
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 14 Apr 2023, 13:04
.. just some questions though
1/ can u pls clarify the use of ASM i/o plain ASSEMBLE ?
... in calminstruction struct?
Code:
asm mvmacro ?, struct?.xstruct
    

... in calminstruction struct?.xstruct
Code:
asm mvmacro struct?.xstruct, ?
    

... why not simply do sthg like
arrange cmd, =mvmacro ?, struct?.xstruct
assemble cmd

and
arrange cmd, =mvmacro struct?.xstruct, ?
assemble cmd




+
obviously -related :
2/ can u pls clarify how calminstruction calminstruction?.asm? work ?
(had a look at the impl. but still remains unclear to me.... i kinda understand that it's aiming to deal with context issue, but really don't get the details)
Post 14 Apr 2023, 13:04
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8346
Location: Kraków, Poland
Tomasz Grysztar 14 Apr 2023, 13:58
fabbel wrote:
... why not simply do sthg like
arrange cmd, =mvmacro ?, struct?.xstruct
assemble cmd
To be exact, you would have to do it this way:
Code:
arrange cmd, =mvmacro ?, =struct?.=xstruct
assemble cmd    
Not only it's less readable and more error-prone, but it also defines two commands to be executed when the CALM instruction is called. If the line to be assembled does not contain any variable elements, you don't really need that ARRANGE command, the text can be defined statically, like:
Code:
define cmd100 mvmacro ?, struct?.xstruct

calminstruction ; ...
    ; ...
    assemble cmd100    
Now the only command that is executed at instruction run-time is the ASSEMBLE, and the contents of the line is in a global variable.

The "asm" macro does a similar thing, but puts the contents of the line to assemble in a hidden variable. The compiled instruction is again going to contain just a single ASSEMBLE command, referring to static value of variable, only this time this variable is kept private, and also you define the value in the same place where you call it. So "asm" is not only more convenient, but also produces a minimal CALM code (just a single ASSEMBLE instruction) without any additional overhead (all the things that "calminstruction?.asm?" does, are done while compiling the instruction that uses it).

As for the context-related issues you mentioned, this is something that only comes into view when you want the assembled text to refer to symbols that are local to the definition of your CALM instruction. You cannot do that with ARRANGE, because it produces the text at run-time (when your CALM instruction is executed), so this text is then interpreted in the context in which the instruction is invoked. Consider this example:
Code:
calminstruction test
        local cmd, v
        compute v, 'A'
        arrange cmd, =db =v
        assemble cmd
end calminstruction

v = 'B'
test ; produces 'B'    
The compiled macroinstruction "test" executes an ARRANGE command, which makes text "db v", which is then assembled. This all happens at run-time, when the "test" instruction is executed, and so it sees the "v" variable that has value "B". The one where we put the value "A" is a variable local to the definition of the instruction. For the same reason if the command is defined globally, it cannot refer to the symbol that is local to the definition of instruction:
Code:
define cmd db v

calminstruction test
        local v
        compute v, 'A'
        assemble cmd
end calminstruction

v = 'B'
test ; again produces 'B'    
This is where the "initsym" macro comes to the rescue:
Code:
calminstruction calminstruction?.initsym? var*, val&
        publish var, val
end calminstruction    
This command simply defines a symbolic variable, but because it does it at the time when it is executed, which is during the definition of another CALM instruction, it does so in the local context of that definition. The text passed to the macro is marked as being in that local context. So this time, when you define a text containing the "v" symbol, this symbol can refer to the variable local to the definition:
Code:
calminstruction test
        local cmd, v
        compute v, 'A'
        initsym cmd, db v
        assemble cmd
end calminstruction

v = 'B'
test ; produces 'A'    
Note that "initsym" does not produce any commands to be compiled into the code of "test" instruction, it simply defines a variable at the time of definition, this value remains static and is then referred to by the ASSEMBLE command. And this static value also has meta-information about context, which points to "v" symbol that is local to the definition of "test".

And now, if we define an "asm" command, the text given to it also has the local context, therefore it too allows to access the symbols local to the definition:
Code:
calminstruction test
        local v
        compute v, 'A'
        asm db v
end calminstruction

v = 'B'
test ; produces 'A'    
I recently started using this self-contained version of "asm" command, which only requires "initsym":
Code:
calminstruction calminstruction?.asm? line&
        local   name, i
        initsym name, name.0
        match   name.i, name
        compute i, i+1
        arrange name, name.i
        publish name:, line
        arrange line, =assemble name
        assemble line
end calminstruction    
I think that this variant may be easier to follow. Note that it uses ARRANGE to produce the ASSEMBLE command to be compiled, with a variable portion that is replaced with a new name every time. Also, because the prefix of this name has been defined with "initsym", it keeps the context local to the definition of "calminstruction?.asm?", so all the variables it makes (called "name.1", "name.2", and so on) are kept there, out of reach of any other code.

It also demonstrates how ARRANGE and MATCH work like a mirror of each other. "match name.i, name" splits the text kept in "name" variable into parts, and puts them into "name" and "i" variables. Then "arrange name, name.i" takes the values of these two variables, puts them together and places the composite text into "name" again. The initial value of "name" has been defined as "name.0", but it could use another local prefix, even "i.0" would work. If you follow this through, I believe it should give you some general intuition about CALM. It is important to distinguish what happens at the time of definition, and what at the run-time of the compiled macro. And keep in mind that for instruction like "calminstruction?.asm?" the run-time happens during the definition-time of yet another instruction.
Post 14 Apr 2023, 13:58
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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.