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 > help with some macros

Author
Thread Post new topic Reply to topic
username



Joined: 30 Jun 2017
Posts: 11
help with some macros
Hi, I just registered to the forum.
I need some help with some macros
(i'm just amateur)

I have the following code:


Code:
format PE GUI 4.0
entry start

include 'win32ax.inc'

eaxul equ eax
ebxul equ ebx
ecxul equ ecx
edxul equ edx
ediul equ edi
esiul equ esi
ebpul equ ebp


    macro ext instr
     {
      macro instr op1,op2,op3
       \{
        instr op1,op2
        if op3 eq
         ;nothing
        else
          if (op3 mod 2)=0
             exchange eaxul,ebxul
          else
             exchange ecxul,edxul
          end if
        end if
       \}
     }


macro show
{
 display eax=eaxul ebx=ebxul ecx=ecxul edx=edxul edi=ediul esi=esiul ebp=ebpul
}


macro exchange var1,var2
{
    local tmp1,tmp2,tmp3

    tmp1 equ var1
    tmp2 equ var2

    xchg var1,var2

    tmp3 equ tmp1
    tmp1 equ tmp2
    tmp2 equ tmp3

    var1 equ tmp1
    var2 equ tmp2
}


section '.text' code readable executable

  start:

        xor eaxul,eaxul
        exchange eaxul,edxul
        exchange ecxul,ediul
        exchange ecxul,eaxul
        exchange esiul,ebxul
        exchange ebxul,eaxul
        exchange ebpul,ediul
        exchange esiul,eaxul
        exchange edxul,ediul

        inc eaxul

        exchange edxul,ecxul

        add eaxul,2

        exchange eaxul,ebpul

        add eaxul,2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;  at this line eaxul = a register which has value 5
;;;;;;;  to show which register is eaxul, use show bellow
;;;;;;;  to run the program just comment show
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        show

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;  it shows that eaxul is ecx
;;;;;;;  and run in a debugger, ecx = 5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;  when calling a windows API, some registers
;;;;;;;  have to be the original ones
;;;;;;;  for example ebxul=ebx, ediul=edi
;;;;;;;  i need a macro which restores the registers passed as arguments
;;;;;;;  for example if i need to restore edxul and eaxul to original,
;;;;;;;  i use "restore edxul,eaxul"
;;;;;;;  how to write such a macro?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;  now use extended sub instruction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
         ext sub
         sub eaxul,1     ; substracts 1 from ecx, correct
         sub eaxul,2     ; substracts 2 from edi ?????????


  retn  




to explain the code a little, i use the registers and exchange them with one another in the output exe, but in the source code to address them with some equ constants. maybe you understand better if you read the code

i need help with a restore macro, which will restore the registers to their original values.
also, on the line "sub eaxul,2" in the output file it substracts 2 from edi instead of ecx. i think it has something to do with how the preprocessor handles the macros. is it a way to make it substract 2 from the ecx (as intended)?

thank you!
Post 30 Jun 2017, 09:07
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
Okay, your macro is tricky because equ is a textual replacement and things get confusing quickly.

Rather than try to fix it manually here I would like to suggest you assemble the "PREPSRC.ASM" file (which can be found the TOOLS folder in the fasm download). Run that over your source code and examine the output to see all of the things that happened in the preprocessor stage during assembly. In that you will see all of the textual replacements that happen.
Post 30 Jun 2017, 10:43
View user's profile Send private message Visit poster's website Reply with quote
username



Joined: 30 Jun 2017
Posts: 11
ok, i remove the 'win32ax.inc' line, then i run the prepsrc over file.fas and got this output:


Code:

format PE GUI 4.0
entry start


;eaxul equ eax
;ebxul equ ebx
;ecxul equ ecx
;edxul equ edx
;ediul equ edi
;esiul equ esi
;ebpul equ ebp


;macro ext instr
;{
; macro instr op1,op2,op3
; \{
; instr op1,op2
; if op3 eq
;
; else
; if(op3 mod 2)=0
; exchange eaxul,ebxul
; else
; exchange ecxul,edxul
; end if
; end if
; \}
;}


;macro show
;{
; display eax=eaxul ebx=ebxul ecx=ecxul edx=edxul edi=ediul esi=esiul ebp=ebpul
;}






;macro exchange var1,var2
;{
; local tmp1,tmp2,tmp3
;
; tmp1 equ var1
; tmp2 equ var2
;
; xchg var1,var2
;
; tmp3 equ tmp1
; tmp1 equ tmp2
; tmp2 equ tmp3
;
; var1 equ tmp1
; var2 equ tmp2
;}


section '.text' code readable executable

start:

xor eax,eax
;exchange eaxul,edxul
; tmp1?0 tmp2?1 tmp3?2
;tmp1?0 equ eax
;tmp2?1 equ edx
xchg eax,edx
;tmp3?2 equ eax
;tmp1?0 equ edx
;tmp2?1 equ eax
;eaxul equ edx
;edxul equ eax
;exchange ecxul,ediul
; tmp1?3 tmp2?4 tmp3?5
;tmp1?3 equ ecx
;tmp2?4 equ edi
xchg ecx,edi
;tmp3?5 equ ecx
;tmp1?3 equ edi
;tmp2?4 equ ecx
;ecxul equ edi
;ediul equ ecx
;exchange ecxul,eaxul
; tmp1?6 tmp2?7 tmp3?8
;tmp1?6 equ edi
;tmp2?7 equ edx
xchg edi,edx
;tmp3?8 equ edi
;tmp1?6 equ edx
;tmp2?7 equ edi
;ecxul equ edx
;eaxul equ edi
;exchange esiul,ebxul
; tmp1?9 tmp2?A tmp3?B
;tmp1?9 equ esi
;tmp2?A equ ebx
xchg esi,ebx
;tmp3?B equ esi
;tmp1?9 equ ebx
;tmp2?A equ esi
;esiul equ ebx
;ebxul equ esi
;exchange ebxul,eaxul
; tmp1?C tmp2?D tmp3?E
;tmp1?C equ esi
;tmp2?D equ edi
xchg esi,edi
;tmp3?E equ esi
;tmp1?C equ edi
;tmp2?D equ esi
;ebxul equ edi
;eaxul equ esi
;exchange ebpul,ediul
; tmp1?F tmp2?G tmp3?H
;tmp1?F equ ebp
;tmp2?G equ ecx
xchg ebp,ecx
;tmp3?H equ ebp
;tmp1?F equ ecx
;tmp2?G equ ebp
;ebpul equ ecx
;ediul equ ebp
;exchange esiul,eaxul
; tmp1?I tmp2?J tmp3?K
;tmp1?I equ ebx
;tmp2?J equ esi
xchg ebx,esi
;tmp3?K equ ebx
;tmp1?I equ esi
;tmp2?J equ ebx
;esiul equ esi
;eaxul equ ebx
;exchange edxul,ediul
; tmp1?L tmp2?M tmp3?N
;tmp1?L equ eax
;tmp2?M equ ebp
xchg eax,ebp
;tmp3?N equ eax
;tmp1?L equ ebp
;tmp2?M equ eax
;edxul equ ebp
;ediul equ eax

inc ebx

;exchange edxul,ecxul
; tmp1?O tmp2?P tmp3?Q
;tmp1?O equ ebp
;tmp2?P equ edx
xchg ebp,edx
;tmp3?Q equ ebp
;tmp1?O equ edx
;tmp2?P equ ebp
;edxul equ edx
;ecxul equ ebp

add ebx,2

;exchange eaxul,ebpul
; tmp1?R tmp2?S tmp3?T
;tmp1?R equ ebx
;tmp2?S equ ecx
xchg ebx,ecx
;tmp3?T equ ebx
;tmp1?R equ ecx
;tmp2?S equ ebx
;eaxul equ ecx
;ebpul equ ebx

add ecx,2




!!!!!!!!!!!!!!UNTIL HERE EVERYTHING IS OK!!!!!!!!!!!!!!!!!!!!




















;ext sub
;macro sub op1,op2,op3
;{
; sub op1,op2
; if op3 eq
; else
; if(op3 mod 2)=0
; exchange eaxul,ebxul
; else
; exchange ecxul,edxul
; end if
; end if
;}

;sub eaxul,1
sub ecx,1
if eq
else
if(mod 2)=0
;exchange eaxul,ebxul
; tmp1?U tmp2?V tmp3?W
;tmp1?U equ ecx
;tmp2?V equ edi
xchg ecx,edi               !!!!!!!!!!!!this don't show in the exebut eaxul gets edi!!!!!!!!!!!!!!!!!!
;tmp3?W equ ecx
;tmp1?U equ edi
;tmp2?V equ ecx
;eaxul equ edi
;ebxul equ ecx
else
;exchange ecxul,edxul
; tmp1?X tmp2?Y tmp3?Z
;tmp1?X equ ebp
;tmp2?Y equ edx
xchg ebp,edx
;tmp3?Z equ ebp
;tmp1?X equ edx
;tmp2?Y equ ebp
;ecxul equ edx
;edxul equ ebp
end if
end if

;sub eaxul,2
sub edi,2
if eq
else
if(mod 2)=0
;exchange eaxul,ebxul
; tmp1?a tmp2?b tmp3?c
;tmp1?a equ edi
;tmp2?b equ ecx
xchg edi,ecx
;tmp3?c equ edi
;tmp1?a equ ecx
;tmp2?b equ edi
;eaxul equ ecx
;ebxul equ edi
else
;exchange ecxul,edxul
; tmp1?d tmp2?e tmp3?f
;tmp1?d equ edx
;tmp2?e equ ebp
xchg edx,ebp
;tmp3?f equ edx
;tmp1?d equ ebp
;tmp2?e equ edx
;ecxul equ ebp
;edxul equ edx
end if
end if

retn





it seems that the preprocessor processes ALL the equ instructions first disregarding if they are inside some preprocessing condition, then checks the conditions to output the asm instructions?

any workaround to this?
Post 30 Jun 2017, 12:19
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
The thing to realise is the separation of fasm's layers. The assembler stage will process the if, else and end if after the preprocessor has finished.

The "workaround" is to use preprocessor conditional structures with match.
Post 30 Jun 2017, 12:26
View user's profile Send private message Visit poster's website Reply with quote
username



Joined: 30 Jun 2017
Posts: 11
if you find a little spare time please post a working solution
thank you
Post 30 Jun 2017, 12:31
View user's profile Send private message Reply with quote
username



Joined: 30 Jun 2017
Posts: 11
i modified a little a macro using the match directive, but i still am not able to get the results i need. i don't know how to use match to behave like an if statement


Code:

    macro ext instr
     {
      macro instr op1,op2,op3
       \{
        instr op1,op2
        if op3 eq
         ;nothing
        else

          match tempop3
          \\{
             temp2 = temp mod 2
             if temp2 = 0
                 match 0,temp2               ???? how to use match to make it execute on condition when temp2 = 0 ????
                 \\\{ exchange eaxul,ebxul \\\}
             else
                 match 1,temp2               ???? how to use match to make it execute on condition when temp2 = 1 ????
                 \\\{ exchange ecxul,edxul \\\}
             end if
          \\}

        end if
       \}
     }



i tried match =0,temp2 ; match 0,=temp2 etc but i don't get the expected results
if i don't get the use of match, please show me how to use it properly on my example

so i need to evaluate and act accordingly (on conditions) some equations at the preprocessor layer, if i understand correctly. i saw the match directive example

match =TRUE, DEBUG { include 'debug.inc' }

but in my example it doesn't work if i use

match =0,temp2 {....}
Post 03 Jul 2017, 05:58
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
You are still mixing if and match. Also all expressions are computed during the assembly stage so match has no knowledge of what value a numeric variable will have. Match only deals with string data, not numbers.

You can use equ and match together. Equ also deals with only string data.

There is one preprocessor directive that can evaluate strings as numbers, that is rept. But it also generates string results of the numbers it evaluates. So you can use "rept x,temp mod 2" for example and x will then be equal to either "0" or "1" as a string. Then use match to see if x is 0 or 1.
Post 04 Jul 2017, 07:21
View user's profile Send private message Visit poster's website Reply with quote
username



Joined: 30 Jun 2017
Posts: 11
thank you for clarification

at the preprocessor layer is it possible to obtain a number without explicitly write it or get to it by calculations? something like $ ?
Post 04 Jul 2017, 08:18
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
You can't get the value of $ within the preprocessor. Only the assembly stage knows $.

If you use "temp = 4" then the preprocessor cannot know the value of temp. Even rept can't see the value of 4 because it is an expression, not an equate. You would have to use "temp equ 4" or the similar "define temp 4".


Last edited by revolution on 04 Jul 2017, 11:01; edited 1 time in total
Post 04 Jul 2017, 08:26
View user's profile Send private message Visit poster's website Reply with quote
username



Joined: 30 Jun 2017
Posts: 11
nevermind, thanks again
Post 04 Jul 2017, 08:41
View user's profile Send private message 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


Powered by phpBB © 2001-2005 phpBB Group.

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