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: 75
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: 6865
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: 75
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: 6865
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: 75
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: 6865
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: 75
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: 6865
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: 75
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: 6865
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: 75
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: 6865
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: 75
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: 6865
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: 75
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: 75
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: 75
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: 6865
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: 75
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: 6865
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 © 2004-2018, Tomasz Grysztar.

Powered by rwasa.