flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > help needed:in struct label dislike varvirtual wrapper

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 25 Oct 2019, 14:03
Code:
include 'proc32.inc'

macro varvirtual definition& {
        match =at addr, definition \{
                macro @virtual@ name,def,[val] \\{
                 \\common
                        \\local ..var
                        ..var def val
                        define name ..var+addr \\}

                macro endv \\{
                        purge label,@virtual@,endv
                        restruc db,du,dw,dp,dd,dt,dq
                        restruc rb,rw,rp,rd,rt,rq
                        end virtual \\}

                macro label def \\{ match . type,def> \\\{ @virtual@ .,label,<type \\\} \\}
                struc db [val] \\{ \common @virtual@ .,db,val \\}
                struc du [val] \\{ \common @virtual@ .,du,val \\}
                struc dw [val] \\{ \common @virtual@ .,dw,val \\}
                struc dp [val] \\{ \common @virtual@ .,dp,val \\}
                struc dd [val] \\{ \common @virtual@ .,dd,val \\}
                struc dt [val] \\{ \common @virtual@ .,dt,val \\}
                struc dq [val] \\{ \common @virtual@ .,dq,val \\}
                struc rb cnt \\{ @virtual@ .,rb cnt, \\}
                struc rw cnt \\{ @virtual@ .,rw cnt, \\}
                struc rp cnt \\{ @virtual@ .,rp cnt, \\}
                struc rd cnt \\{ @virtual@ .,rd cnt, \\}
                struc rt cnt \\{ @virtual@ .,rt cnt, \\}
                struc rq cnt \\{ @virtual@ .,rq cnt, \\}

                virtual at 0 \} }

espFixer=0
macro parameters [arg] {
 common local argsize,localbytes,espPos,..retaddr
        define retaddr esp+espFixer
        virtual at 0
                ..retaddr dd ?
                        define retaddr ..retaddr+esp+espFixer
                if ~arg eq
 forward
                        local ..arg
                        ..arg dd ?
                        define arg ..arg+esp+espFixer
 common
                end if
                argsize = $-4
        end virtual
        espPos = 0
        macro locals \{
                \local espPosInner
                espPosInner = espPos
                varvirtual at espPosInner-localbytes+esp+espFixer
                        macro label def \\{ match . type,def> \\\{ esplocal@proc .,label,<type \\\} \\}
                        struc db [val] \\{ \\common esplocal@proc .,db,val \\}
                        struc du [val] \\{ \\common esplocal@proc .,du,val \\}
                        struc dw [val] \\{ \\common esplocal@proc .,dw,val \\}
                        struc dp [val] \\{ \\common esplocal@proc .,dp,val \\}
                        struc dd [val] \\{ \\common esplocal@proc .,dd,val \\}
                        struc dt [val] \\{ \\common esplocal@proc .,dt,val \\}
                        struc dq [val] \\{ \\common esplocal@proc .,dq,val \\}
                        struc rb cnt \\{ esplocal@proc .,rb cnt, \\}
                        struc rw cnt \\{ esplocal@proc .,rw cnt, \\}
                        struc rp cnt \\{ esplocal@proc .,rp cnt, \\}
                        struc rd cnt \\{ esplocal@proc .,rd cnt, \\}
                        struc rt cnt \\{ esplocal@proc .,rt cnt, \\}
                        struc rq cnt \\{ esplocal@proc .,rq cnt, \\} \}

        macro endl \{
                        purge label
                        restruc db,du,dw,dp,dd,dt,dq
                        restruc rb,rw,rp,rd,rt,rq
                        espPos = espPos+(($-$$+3) and (not 3))
                        endv \}

        macro endp \{
                localbytes = espPos
                match any,arg \\{
 forward
                        restore arg
common
                \\}
                restore retaddr
                purge endp,push,pushd,pop,sub,add,invoke,cominvk,comcall,stdcall,ret,locals,endl
                match all,all@vars \\{ restore all \\}
                restore all@vars
                espFixer=0 \}

        macro pushd [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                pushd    arg1
                espFixer =..tmp+4
        \}

        macro push [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                push     arg1
                espFixer =..tmp+4
        \}

        macro pop [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                pop      arg1
                espFixer =..tmp-4
        \}

        macro sub arg1,arg2 \{
                sub arg1,arg2
                match   =esp,arg1 \\{ espFixer =espFixer+arg2 \\} \}

        macro add arg1,arg2 \{
                add arg1,arg2
                match   =esp,arg1 \\{ espFixer =espFixer-arg2 \\} \}

        macro invoke proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                invoke proc,arg1
                espFixer =..tmp \}

        macro cominvk object,proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                cominvk object,proc,arg1
                espFixer =..tmp \}

        macro comcall handle,interface,proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                comcall handle,interface,proc,arg1
                espFixer =..tmp \}

        macro stdcall proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                stdcall proc,arg1
                espFixer =..tmp \}

        macro ret arg1:argsize \{
                if localbytes
                        add esp, localbytes
                end if
                ret arg1 \}

        if localbytes
                sub esp, localbytes
        end if }

macro esplocal@proc name,def,val& {
        name def val }

macro esplocal@proc name,def,val& {
        match vars, all@vars \{ all@vars equ all@vars, \}
        all@vars equ all@vars name
        name def val }

macro procedure definition& {
        match (args),definition \{ parameters args \}
        match (),definition \{ parameters \} }     

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.


Last edited by ProMiNick on 29 Oct 2019, 08:41; edited 2 times in total
Post 25 Oct 2019, 14:03
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 28 Oct 2019, 15:05
All tests passed

test:
Code:
use32
A: procedure (U,V)
        locals
                B dd 5
                F dq 7
        endl
        locals
                C db 0
                D dd 7,8
        endl
        ;            locals1  locals2
        stackframe = 12     + 12
        pushsize =4
        assert espFixer=stackframe
        assert retaddr=esp+espFixer+0
        assert U=esp+espFixer+4
        assert V=esp+espFixer+8
        assert B=esp+espFixer-stackframe+0
        assert F=esp+espFixer-stackframe+4
        assert C=esp+espFixer-stackframe+$C
        assert D=esp+espFixer-stackframe+$D
        mov     eax, [B]
        mov     eax, dword[F]
        mov     eax, dword[C]
        mov     eax, [D]
        push [retaddr]
        assert espFixer=stackframe+pushsize
        assert retaddr=esp+espFixer+0
        assert U=esp+espFixer+4
        assert V=esp+espFixer+8
        assert B=esp+espFixer-stackframe+0
        assert F=esp+espFixer-stackframe+4
        assert C=esp+espFixer-stackframe+$C
        assert D=esp+espFixer-stackframe+$D
        call    0
        mov     eax, [B]
        ret
endp    

I wasn`t interested in initial values on stack - so their realization is cuted off.
Post 28 Oct 2019, 15:05
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 29 Oct 2019, 08:38
more general test failed:

Code:
include 'struct.inc'
include 'proc32.inc'

macro varvirtual definition& {
        match =at addr, definition \{
                macro @virtual@ name,def,[val] \\{
                 \\common
                        \\local ..var
                        ..var def val
                        define name ..var+addr \\}

                macro endv \\{
                        purge label,@virtual@,endv
                        restruc db,du,dw,dp,dd,dt,dq
                        restruc rb,rw,rp,rd,rt,rq
                        end virtual \\}

                macro label def \\{ match . type,def> \\\{ @virtual@ .,label,<type \\\} \\}
                struc db [val] \\{ \common @virtual@ .,db,val \\}
                struc du [val] \\{ \common @virtual@ .,du,val \\}
                struc dw [val] \\{ \common @virtual@ .,dw,val \\}
                struc dp [val] \\{ \common @virtual@ .,dp,val \\}
                struc dd [val] \\{ \common @virtual@ .,dd,val \\}
                struc dt [val] \\{ \common @virtual@ .,dt,val \\}
                struc dq [val] \\{ \common @virtual@ .,dq,val \\}
                struc rb cnt \\{ @virtual@ .,rb cnt, \\}
                struc rw cnt \\{ @virtual@ .,rw cnt, \\}
                struc rp cnt \\{ @virtual@ .,rp cnt, \\}
                struc rd cnt \\{ @virtual@ .,rd cnt, \\}
                struc rt cnt \\{ @virtual@ .,rt cnt, \\}
                struc rq cnt \\{ @virtual@ .,rq cnt, \\}

                virtual at 0 \} }

espFixer=0
macro parameters [arg] {
 common local argsize,localbytes,espPos,..retaddr
        define retaddr esp+espFixer
        virtual at 0
                ..retaddr dd ?
                        define retaddr ..retaddr+esp+espFixer
                if ~arg eq
 forward
                        local ..arg
                        ..arg dd ?
                        define arg ..arg+esp+espFixer
 common
                end if
                argsize = $-4
        end virtual
        espPos = 0
        macro locals \{
                \local espPosInner
                espPosInner = espPos
                varvirtual at espPosInner-localbytes+esp+espFixer
                        macro label def \\{ match . type,def> \\\{ esplocal@proc .,label,<type \\\} \\}
                        struc db [val] \\{ \\common esplocal@proc .,db,val \\}
                        struc du [val] \\{ \\common esplocal@proc .,du,val \\}
                        struc dw [val] \\{ \\common esplocal@proc .,dw,val \\}
                        struc dp [val] \\{ \\common esplocal@proc .,dp,val \\}
                        struc dd [val] \\{ \\common esplocal@proc .,dd,val \\}
                        struc dt [val] \\{ \\common esplocal@proc .,dt,val \\}
                        struc dq [val] \\{ \\common esplocal@proc .,dq,val \\}
                        struc rb cnt \\{ esplocal@proc .,rb cnt, \\}
                        struc rw cnt \\{ esplocal@proc .,rw cnt, \\}
                        struc rp cnt \\{ esplocal@proc .,rp cnt, \\}
                        struc rd cnt \\{ esplocal@proc .,rd cnt, \\}
                        struc rt cnt \\{ esplocal@proc .,rt cnt, \\}
                        struc rq cnt \\{ esplocal@proc .,rq cnt, \\} \}

        macro endl \{
                        purge label
                        restruc db,du,dw,dp,dd,dt,dq
                        restruc rb,rw,rp,rd,rt,rq
                        espPos = espPos+(($-$$+3) and (not 3))
                        endv \}

        macro endp \{
                localbytes = espPos
                match any,arg \\{
 forward
                        restore arg
common
                \\}
                restore retaddr
                purge endp,push,pushd,pop,sub,add,invoke,cominvk,comcall,stdcall,ret,locals,endl
                match all,all@vars \\{ restore all \\}
                restore all@vars
                espFixer=0 \}

        macro pushd [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                pushd    arg1
                espFixer =..tmp+4
        \}

        macro push [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                push     arg1
                espFixer =..tmp+4
        \}

        macro pop [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                pop      arg1
                espFixer =..tmp-4
        \}

        macro sub arg1,arg2 \{
                sub arg1,arg2
                match   =esp,arg1 \\{ espFixer =espFixer+arg2 \\} \}

        macro add arg1,arg2 \{
                add arg1,arg2
                match   =esp,arg1 \\{ espFixer =espFixer-arg2 \\} \}

        macro invoke proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                invoke proc,arg1
                espFixer =..tmp \}

        macro cominvk object,proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                cominvk object,proc,arg1
                espFixer =..tmp \}

        macro comcall handle,interface,proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                comcall handle,interface,proc,arg1
                espFixer =..tmp \}

        macro stdcall proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                stdcall proc,arg1
                espFixer =..tmp \}

        macro ret arg1:argsize \{
                if localbytes
                        add esp, localbytes
                end if
                ret arg1 \}

        if localbytes
                sub esp, localbytes
        end if }

macro esplocal@proc name,def,val& {
        name def val }

macro esplocal@proc name,def,val& {
        match vars, all@vars \{ all@vars equ all@vars, \}
        all@vars equ all@vars name
        name def val }

macro procedure definition& {
        match (args),definition \{ parameters args \}
        match (),definition \{ parameters \} }

struct MyStruct
        noMatter dd ?
ends

use32
A: procedure (U,V)
        locals
                mstr MyStruct ; crashed here
        endl
        ;            locals1  locals2
        stackframe = sizeof.MyStruct
        pushsize =4
        assert espFixer=stackframe
        assert retaddr=esp+espFixer+0
        assert U=esp+espFixer+4
        assert V=esp+espFixer+8
        assert mstr=esp+espFixer-stackframe+0
        push [retaddr]
        assert espFixer=stackframe+pushsize
        assert retaddr=esp+espFixer+0
        assert U=esp+espFixer+4
        assert V=esp+espFixer+8
        assert mstr=esp+espFixer-stackframe+0
        call    0
        ret
endp    


illegal instruction: ..var?C label<>
Code:
[+] mstr MyStruct
 |-[+] match no, @struct \\\{ label \\..base
    |-[+] macro label def \\{ match . type,def> \\\{ esplocal@proc .,label,<type \\\} \\}
       |-[+] name def val }
          |-[+] struc label type { label . type }
             |-[+] macro label def \\{ match . type,def> \\\{ @virtual@ .,label,<type \\\} \\}
                |-[+] ..var def val    

I suppose struct macroset dislike varvirtual wrapped arround label definition.

I guess varvirtual is useless in thing what it designed for. I have to return to manualy espFixer adder for memory addressed with locals. It is sad.
Post 29 Oct 2019, 08:38
View user's profile Send private message Send e-mail Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1150
Location: Russian Federation
comrade 31 Oct 2019, 00:16
Вопрос в чём? Что вы пытаетесь осуществить?

What is the question? What are you trying to do?
Post 31 Oct 2019, 00:16
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 31 Oct 2019, 06:44
I trying to do automated esp call frame.
I succesfuly build couple of dlls with esp frames only.
And wish to make this solution more friendly to newbies.

Offset of locals (and parameters) in case of esp frame have two components: 1 - constant - relative to size of such locals and their internal structure; 2 - predictable variable - relative to stack modifier instructions in preciding instruction flow (except xchg & mov esp with REG or [memory]).
If we split this components in separate addends in memory operands - all ok.
If we combining them in one identifier - 2 ways: 1 - redefine all local identifiers with their internal structure; 2 - initialy define every member of such identifiers with variable addend.
1 solution is heavy for compilation (every push|pop, every sub|add esp will redefine all locals).
2nd solution require support of variable base of virtual block of support of that at level of struct.inc macro set.

how I could now:
A: procedure(B,C)
virtual at 0
loc1 TYPEDEFINEDWITHSTRUCT
;...
end virtual
sub esp, sizeof.TYPEDEFINEDWITHSTRUCT ;+ ....
define localbase esp - sizeof.TYPEDEFINEDWITHSTRUCT +espFixer
mov eax,[B] ; all OK, I don`t required in additional addent espFixer to B & C
mov [C], eax ; I can make them to contain it
;but in case of locals a have to add localbase or espFixer (every intruction that affects esp - affects espFixer)
mov eax,[loc1+localbase] ; 2nd addent is my problem, but may be it was no so unfriendly as I thought.

final version
Code:
espFixer=0
macro parameters [arg] {
 common local argsize,localbytes,espPos,..retaddr
        virtual at 0
                ..retaddr dd ?
                        define retaddr ..retaddr+esp+espFixer
                        define localbase ..retaddr+esp+espFixer-localbytes
                if ~arg eq
 forward
                        local ..arg
                        ..arg dd ?
                        define arg ..arg+esp+espFixer
 common
                end if
                argsize = $-4
        end virtual
        espPos = 0
        macro locals \{
                \local espPosInner
                espPosInner = espPos
                virtual at espPosInner
                        macro label def \\{ match . type,def> \\\{ esplocal@proc .,label,<type \\\} \\}
                        struc db [val] \\{ \\common esplocal@proc .,db,val \\}
                        struc du [val] \\{ \\common esplocal@proc .,du,val \\}
                        struc dw [val] \\{ \\common esplocal@proc .,dw,val \\}
                        struc dp [val] \\{ \\common esplocal@proc .,dp,val \\}
                        struc dd [val] \\{ \\common esplocal@proc .,dd,val \\}
                        struc dt [val] \\{ \\common esplocal@proc .,dt,val \\}
                        struc dq [val] \\{ \\common esplocal@proc .,dq,val \\}
                        struc rb cnt \\{ esplocal@proc .,rb cnt, \\}
                        struc rw cnt \\{ esplocal@proc .,rw cnt, \\}
                        struc rp cnt \\{ esplocal@proc .,rp cnt, \\}
                        struc rd cnt \\{ esplocal@proc .,rd cnt, \\}
                        struc rt cnt \\{ esplocal@proc .,rt cnt, \\}
                        struc rq cnt \\{ esplocal@proc .,rq cnt, \\} \}

        macro endl \{
                        purge label
                        restruc db,du,dw,dp,dd,dt,dq
                        restruc rb,rw,rp,rd,rt,rq
                        espPos = espPos+(($-$$+3) and (not 3))
                        end virtual \}

        macro endp \{
                localbytes = espPos
                match any,arg \\{
 forward
                        restore arg
common
                \\}
                restore retaddr,localbase
                purge endp,push,pushd,pop,sub,add,invoke,cominvk,comcall,stdcall,ret,locals,endl
                match all,all@vars \\{ restore all \\}
                restore all@vars
                espFixer=0 \}

        macro pushd [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                pushd    arg1
                espFixer =..tmp+4
        \}

        macro push [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                push     arg1
                espFixer =..tmp+4
        \}

        macro pop [arg1] \{
        \common  \local ..tmp
        \forward
                ..tmp = espFixer
                pop      arg1
                espFixer =..tmp-4
        \}

        macro sub arg1,arg2 \{
                sub arg1,arg2
                match   =esp,arg1 \\{ espFixer =espFixer+arg2 \\} \}

        macro add arg1,arg2 \{
                add arg1,arg2
                match   =esp,arg1 \\{ espFixer =espFixer-arg2 \\} \}

        macro invoke proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                invoke proc,arg1
                espFixer =..tmp \}

        macro cominvk object,proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                cominvk object,proc,arg1
                espFixer =..tmp \}

        macro comcall handle,interface,proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                comcall handle,interface,proc,arg1
                espFixer =..tmp \}

        macro stdcall proc,[arg1] \{
        \common \local ..tmp
                ..tmp = espFixer
                stdcall proc,arg1
                espFixer =..tmp \}

        macro ret arg1:argsize \{
                if localbytes
                        add esp, localbytes
                end if
                ret arg1 \}

        if localbytes
                sub esp, localbytes
        end if }

macro esplocal@proc name,def,[val] {
 common
        name def val }

macro esplocal@proc name,def,[val] {
 common
        match vars, all@vars \{ all@vars equ all@vars, \}
        all@vars equ all@vars name
        local ..var
        ..var def val
        define name ..var}

macro procedure definition& {
        match (args),definition \{ parameters args \}
        match (),definition \{ parameters \} }    


test:
Code:
include 'struct.inc'
include 'proc32.inc'    

Code:
struct OPENFILENAME
  lStructSize       dd ?
  hwndOwner         dd ?
  hInstance         dd ?
  lpstrFilter       dd ?
  lpstrCustomFilter dd ?
  nMaxCustFilter    dd ?
  nFilterIndex      dd ?
  lpstrFile         dd ?
  nMaxFile          dd ?
  lpstrFileTitle    dd ?
  nMaxFileTitle     dd ?
  lpstrInitialDir   dd ?
  lpstrTitle        dd ?
  Flags             dd ?
  nFileOffset       dw ?
  nFileExtension    dw ?
  lpstrDefExt       dd ?
  lCustData         dd ?
  lpfnHook          dd ?
  lpTemplateName    dd ?
ends    

Code:
use32
A: procedure (U,V)
        locals
                ofn OPENFILENAME
        endl
        locals
                ofn2 OPENFILENAME
        endl
        ;            locals1  locals2
        stackframe = sizeof.OPENFILENAME + sizeof.OPENFILENAME
        pushsize =4
        assert espFixer=stackframe
        assert retaddr=esp+espFixer+0
        assert U=esp+espFixer+4
        assert V=esp+espFixer+8
        assert ofn=0
        assert ofn2=0+sizeof.OPENFILENAME
        assert localbase=esp+espFixer+0-stackframe
        push 0
        push [ofn2.lStructSize+localbase] ; lets assume that it is more honest to unhide localbase addend in locals member
        call    0
        ret
endp    
Post 31 Oct 2019, 06:44
View user's profile Send private message Send e-mail 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.