flat assembler
Message board for the users of flat assembler.

flat assembler > Macroinstructions > fasmg as preprocessor

Goto page Previous  1, 2, 3  Next
Author
Thread Post new topic Reply to topic
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
BTW , what this line means?

dd print-block_1h-0Ah
Post 21 Feb 2017, 15:42
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
emil wrote:
BTW , what this line means?

dd print-block_1h-0Ah
This is fasm's syntax. It is an address of "print" minus the address of "block_1h" and minus 0Ah.
Post 21 Feb 2017, 15:44
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
oh , you means the call to address by offset?
Post 21 Feb 2017, 15:50
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
emil wrote:
oh , you means the call to address by offset?
For example, if you assemble this:
Code:
block_1h:
db 0E8h
dd print-block_1h-5h
db 0C3h

print:
db 0C3h    
with fasm, the result should be:
Code:
E8 01 00 00 00 C3 C3    
because there block_1h = 0 and print = 6.
Post 21 Feb 2017, 15:57
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
ok , i got it.

i know that must be asked in pelles c forum but i will ask here.

i got error when compiling this fasmg output with PellesC
Code:
// Demonstration of a pre-assembly of blocks of text 

#include <stdio.h>

char* msg = "mix c & fasm is promesing";
void print();

int main(void)
{
    
_asm{
block_1h:
db 68h
dd msg
db 0E8h
dd print-block_1h-0Ah
db 83h,0C4h
db 4h
}

  
}

void print()
{
  puts(msg);
}
    


the line that makes the error is
Code:
dd print-block_1h-0Ah
    


the error is
Quote:

error #3155: [asm] Expression with multiple C symbols is not allowed.
Post 21 Feb 2017, 16:30
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
Have you tried a syntax with "offset" keyword? It is probable that their assembler may expect it:
Code:
dd offset print - offset block_1h - 0Ah    
Post 21 Feb 2017, 16:38
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
the correct thing that PellesC accepted is
Code:
// Demonstration of a pre-assembly of blocks of text 

#include <stdio.h>

char* msg = "mix c & fasm is promesing";
void mprint();

int main(void)
{
    
_asm{

db 68h
dd msg
db 0E8h
dd mprint 
db 83h,0C4h
db 4h
}

  
}

void mprint(void)
{
  puts(msg);
}
    


so can we overload the call macro so that it just print the label only , also the block
label that produced by assemble macro is not needed and make error when compiling with C.
Post 21 Feb 2017, 16:48
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
I'm afraid this will not work correctly, not in all the cases. You cannot just put an address of variable where a relative offset is expected or vice versa. You need to somehow calculate the right values and the expressions generated by fasmg need to be followed exactly.
Post 21 Feb 2017, 16:51
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
ok ,

i tried to solve it by using Invoke macro instead of call like this
Code:

macro Invoce procname
    dbx 1:'db 0E8h',13,10
    dbx 1:'db ',procname,13,10 
end macro

    


and here is the source code

Code:
// Demonstration of a pre-assembly of blocks of text 

#include <stdio.h>

char* msg = "mix c & fasm is promesing";
void print();




int main(void)
{
    
<@         

        push     msg 
        Invoce    print
        add     esp , 4
        
@>
  
}

void print()
{
  puts(msg);
}


    


but it did nor work?
Post 21 Feb 2017, 17:01
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
The opcode of a CALL instruction must contain a relative offset, not the absolute address. You need to somehow compute the difference between the address of "print" and the current address (that's what the "block_x" labels were made for).
Post 21 Feb 2017, 17:04
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
ok , i got it.

but PellesC did not allow us to make more than one label in expression.
Post 21 Feb 2017, 17:23
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
Yes, there seems to be a limitation of the compiler that prevents us from generating the correct relative offset. I wanted to see it myself, so I downloaded the Pelles C and did some tests.

First, it uses the "offset" keyword, as I suspected. So I modified the preprocessing macros to generate expressions with "offset":
Code:
include '80386.inc'

macro extrn? names&   
        iterate name, names   
                element name : `name   
        end iterate   
end macro 

virtual at 0 
        Name_XLAT::   
        repeat 256, c:0   
                if (c >= '0' & c <= '9') \   
                   | c = '+' | c = '-' | c = '/' | c = '*' | c = '=' | c = '<' | c = '>' | c = '(' | c = ')' \   
                   | c = '[' | c = ']' | c = '{' | c = '}' | c = ':' | c = '?' | c = '!' | c = ',' | c = '.' \   
                   | c = '|' | c = '&' | c = '~' | c = '#' | c = '`' | c = '\' | c = '"' | c = "'"   
                        db 0   
                else   
                        db 1   
                end if   
        end repeat   
end virtual   

macro x86.parse_operand_value ns,op   
        local buffer,is_name,auto_extrn  
        define buffer op:   
        while 1   
                match sym tail, buffer   
                        define buffer tail   
                        load is_name:1 from Name_XLAT:`sym and 0FFh   
                        if is_name  
                                if defined auto_extrn.sym & (auto_extrn.sym | ~ defined sym) 
                                        extrn sym  
                                        auto_extrn.sym := 1 
                                else if ~ defined sym  
                                        auto_extrn.sym := 0 
                                end if  
                        end if   
                else   
                        break   
                end match   
        end while   
        x86.parse_operand_value ns,op   
end macro 

virtual at 0   
        HEX_digits:: db '0123456789ABCDEF'    
end virtual   

macro hex? value   
        local number,digit   
        number = value   
        if number < 0   
                dbx 1:'-'   
                number = - number   
        end if   
        repeat 1 + (bsr number shr 2)   
                load digit:1 from HEX_digits:number shr ((%%-%)*4) and 0Fh   
                if %=1 & digit > '9'   
                        dbx 1:'0'   
                end if   
                dbx 1: digit   
        end repeat   
        dbx 1: 'h'   
end macro   

macro db? values&  
        local position,byte  
        position = $  
        iterate value, values  
                byte = value  
                if % = 1  
                        dbx 1:'db '  
                else  
                        dbx 1:','  
                end if   
                hex byte  
                position = position + 1  
                ; org position  
        end iterate   
        dbx 1:13,10  
        org position  
end macro  

macro dw? values&  
        local position,word  
        position = $  
        iterate value, values  
                word = value  
                if % = 1  
                        dbx 1:'dw '  
                else  
                        dbx 1:','  
                end if   
                hex word  
                position = position + 2  
                ; org position  
        end iterate  
        dbx 1:13,10   
        org position  
end macro  

macro dd? values&  
        local position,poly  
        position = $  
        iterate value, values  
                poly = value  
                if % = 1  
                        dbx 1:'dd '  
                else  
                        dbx 1:','  
                end if   
                if poly relativeto 0  
                        hex poly   
                else   
                        repeat elementsof poly  
                                if poly scale % < 0  
                                        dbx 1:'-'   
                                        if - poly scale %  > 1  
                                                hex - poly scale %  
                                                dbx 1:'*'   
                                        end if   
                                else   
                                        if % > 1   
                                                dbx 1:'+'   
                                        end if   
                                        if poly scale % > 1  
                                                hex poly scale %  
                                                dbx 1:'*'   
                                        end if   
                                end if
                                dbx 1:'offset '
                                dbx 1:string poly metadata %  
                        end repeat   
                        if poly scale 0  
                                if poly scale 0 > 0  
                                        dbx 1:'+'   
                                end if   
                                hex poly scale 0  
                        end if   
                end if   
                position = position + 4  
                ; org position  
        end iterate  
        dbx 1:13,10   
        org position  
end macro  

virtual at 0   
 source:: file 'source.txt'    
 .length = $    
end virtual    


position = 0     
block_start = -1    
inline = -1 
block_number = 0 

macro assemble id,text    
        local output,name,base    
        output dbx 1:'block_'    
        hex id    
        load name:$-output from output    
        dbx 1:':',13,10    
        element base : name    
        org base    
        use32    
        eval text    
end macro    

while position < source.length     
        if position < source.length - 1     
                load signature:2 from source:position     
        else     
                load signature:source.length-position from source:position    
        end if     
        if signature = '<@' & block_start < 0     
                block_start = position + 2     
                position = position + 2     
        else if signature = '@>' & block_start > 0     
                load text:position-block_start from source:block_start    
                block_number = block_number + 1    
                assemble block_number,text    
                position = position + 2     
                block_start = -1    
        else if signature and 0FFh  = '!' & block_start < 0 & inline < 0  
                inline = position + 1  
                position = position + 1  
        else if signature and 0FFh  = 10 & block_start < 0 & inline > 0  
                load text:position-inline from source:inline  
                block_number = block_number + 1 
                assemble block_number,text    
                position = position + 1 
                inline = -1           
        else     
                if block_start < 0   & inline < 0      
                        dbx 1:signature and 0FFh    
                end if     
                position = position + 1     
        end if     
end while    

And then I prepared a snippet which uses only instructions that do not need relative displacements:
Code:
// source.txt

#include <stdio.h> 

char* msg = "mix c & fasm";
void print(); 

int main(void) 
{
   _asm{
      <@
        push    [msg]
        mov     ebx,print
        call    ebx
      @>
   }
}

void print(char* m)
{ 
  puts(m);
}    
The generated output is:
Code:
#include <stdio.h>

char* msg = "mix c & fasm";
void print();

int main(void)
{
   _asm{
      block_1h:
db 0FFh,35h
dd offset msg
db 0BBh
dd offset print
db 0FFh,0D3h

   }
}

void print(char* m)
{
  puts(m);
}    
And because it uses no relative offsets and thus has no expressions containing more than one "offset" symbol, it compiles and runs correctly.

So as long as you avoid instructions that need relative offsets, you can already use this with Pelles C. But if you wanted to use it with 64-bit instructions you'd be in a trouble, because they use RIP-relative addressing, so even memory accesses generate opcodes with relative offsets.
Post 21 Feb 2017, 17:39
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
Excellent , Tomasz,

i have modified assemble macro , so that it will automatically generate "_asm{"
and "}" terms

Code:
macro assemble id,text     
        local output,name,base 
        dbx 1:'_asm{',13,10      
        output dbx 1:'block_'     
        hex id     
        load name:$-output from output     
        dbx 1:':',13,10     
        element base : name     
        org base     
        use32     
        eval text 
        dbx 1:'}',13,10         
end macro     
    
Post 21 Feb 2017, 18:04
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
As for the limitations of Pelles C compiler, perhaps you could visit its forum to look for further help. Maybe there is a way to deal with this problem that I am not aware of.
Post 21 Feb 2017, 18:14
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
i will,

thank you.
Post 21 Feb 2017, 18:19
View user's profile Send private message Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
HI Tomasz,

i have a work around solution .

can we overwrite the call macro so that when fasm find a call instruction then pass the line as is , and let the pelles C assembler handle it.

what do you think?
Post 22 Feb 2017, 14:58
View user's profile Send private message Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
BTW it works well with SphinxC-- but needs small modification,

here is the code before reprocessed
Code:
// SphinxC-- & Fasmg
#pragma option w32c //create Windows console EXE.
#pragma option OS //speed optimization

//$ will replaced with SphinxC--main path
#includepath "$\winlib"

#include<windows.h>
#include<MSVCRT.H-->

#Entry  main
#includelib alloc.obj win32.lib MSVCRT.lib ole32.lib

//automatic inserted asm code
#pragma option ia

char* msg = "mix c & fasm"; 

   asm{ 
      <@ 
        push    [msg] 
       
        call     myprint 
        
        ret 
      @> 
   } 
   
int main(void)  
{ 
   call block_1h
   system("pause");
} 

void myprint(char* m) 
{  
  puts(m); 
}
    


and here is the needed code
Code:
// SphinxC-- & Fasmg
#pragma option w32c //create Windows console EXE.
#pragma option OS //speed optimization

//$ will replaced with SphinxC--main path
#includepath "$\winlib"

#include<windows.h>
#include<MSVCRT.H-->

#Entry  main
#includelib alloc.obj win32.lib MSVCRT.lib ole32.lib

//automatic inserted asm code
#pragma option ia

char* msg = "mix c & fasm"; 

   asm{ 
      block_1h:
db 0FFh,35h
dd #msg
db 0E8h
dd #myprint-#block_1h-0Bh
db 0C3h
 
   } 
   
int main(void)  
{ 
   call block_1h
   system("pause");
} 

void myprint(char* m) 
{  
  puts(m); 
}
    


so , the SphinxC-- needs '#' suffix of label , and '#' means address of just like '&' in C language.
Post 22 Feb 2017, 16:49
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
emil wrote:
can we overwrite the call macro so that when fasm find a call instruction then pass the line as is , and let the pelles C assembler handle it.
Well, it should be simple enough that you may be able write this kind of macros yourself:
Code:
macro call? destination
        local position
        position = $
        dbx 1: 'call ',`destination,13,10
        org position
end macro    
Also, if you need to be able to call the labels defined in fasm blocks, you have to pass them through, too:
Code:
struc (label) ? instruction&
        match :, instruction
                label:
                dbx 1: `label,':',13,10
                org label
        else
                label instruction
        end match
end struc    
Post 22 Feb 2017, 16:49
View user's profile Send private message Visit poster's website Reply with quote
emil



Joined: 16 Dec 2003
Posts: 76
Location: egypt
ok ,

why we needs to use " position = $ " and "org position " in our macro

i am trying to get fasmg .
Post 22 Feb 2017, 17:08
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
emil wrote:
why we needs to use " position = $ " and "org position " in our macro
They are there to keep tracking the correct addresses of consecutive instructions. When DBX is used to generate some text into output, it shifts the $ address, but we need to keep it unchanged. On the other hand, DB/DW/DD generated by instruction macros should shift the $ address by the appropriate number of bytes.
Post 22 Feb 2017, 17:16
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:  
Goto page Previous  1, 2, 3  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-2018, Tomasz Grysztar.

Powered by rwasa.