flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
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: 70
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: 6632
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: 70
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: 6632
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: 70
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>

charmsg = "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: 6632
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: 70
Location: egypt
the correct thing that PellesC accepted is

Code:

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

#include <stdio.h>

charmsg = "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: 6632
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: 70
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>

charmsg = "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: 6632
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: 70
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: 6632
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 namenames   
                element name : `name   
        end iterate   
end macro 

virtual at 0 
        Name_XLAT::   
        repeat 256c: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 tailbuffer   
                        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 ((%%-%)*4and 0Fh   
                if %=1 & digit > '9'   
                        dbx 1:'0'   
                end if   
                dbx 1digit   
        end repeat   
        dbx 1'h'   
end macro   

macro db? values&  
        local position,byte  
        position = $  
        iterate valuevalues  
                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 valuevalues  
                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 valuevalues  
                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

charmsg = "mix c & fasm";
void print()

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

void print(charm)

  puts(m);
}

The generated output is:

Code:
#include <stdio.h>

charmsg = "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(charm)
{
  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: 70
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: 6632
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: 70
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: 70
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: 70
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

charmsg = "mix c & fasm"

   asm
      <@ 
        push    [msg
       
        call     myprint 
        
        ret 
      @
   } 
   
int main(void)  

   call block_1h
   system("pause");


void myprint(charm
{  
  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

charmsg = "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(charm
{  
  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: 6632
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: 70
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: 6632
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


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.