News:

Download Pelles C here: http://www.smorgasbordet.com/pellesc/

Main Menu

MACROS

Started by HellOfMice, December 30, 2024, 12:40:48 PM

Previous topic - Next topic

HellOfMice

I try to write a macro creating a window


STATIC_CONTROL_CREATION      MACRO   hParent:REQ,X:REQ,_:REQ,W:REQ,H:REQ,lpszTitle:REQ,dwStyle:REQ
mov   [rsp + 40h],hParent
mov   eax,__H
mov   DWORD PTR [rsp + 20h],__X
mov   DWORD PTR [rsp + 28h],__Y
mov   DWORD PTR [rsp + 30h],__W
mov   DWORD PTR [rsp + 38h],eax      ;; H
xor   ecx,ecx
mov   rax,hInstance
mov   DWORD PTR [rsp + 48h],-1
mov   [rsp + 58h],ecx
lea   rdx,szClass_Static + rip
mov   r8,lpszTitle
mov   r9d,dwStyle
mov   [rsp + 50h],rax      ;; hInstance
call   CreateWindowExA
EXITM
ENDM


and I have the error:

C:\Users\XXXXXXXXXXXXXXXDocuments\# Assembleur #\Awpe\Awpe.asm(868): error: Expected 'ENDM'.

What is the problem?

I rarely use macros and I am not lucky.
I read the help file and all seemed OK.
Why?

Vortex

Hi Philippe,

You don't need EXITM to terminate the macro. ENDM does the job.

Reading Pelles help file :

QuoteThe body may contain one or more EXITM directives, making it possible to return a value from the macro. The use of EXITM signals the macro as being a special function-like macro suitable for use in expressions. All tokens following EXITM up to the following line break will be used as the return value.
Code it... That's all...

HellOfMice

Thank you Vortex


The problem was because I had no new line after ENDM
8)

Vortex

Hi Philippe,

You are welcome. Any specific reason to avoid the invoke macro in your code?
Code it... That's all...

HellOfMice

Hi Vortex,

I add the of making a macro or a procedure.
Like I never make macros, I would lie to try

I has 95 windows to create

That's all

Philippe

Vortex

Hi Philippe,

QuoteLike I never make macros

I understand your choice but invoke is simplifiying a lot of tedious tasks.
Code it... That's all...

HellOfMice

Hello Vortex,

I agree with you but if the code is not pretty I prefer doing it at the hand.
A thing that we should be able to modify easily is the prolog.
I read a lot of thing about it.
I think that if you want an aligned string or structure we must declare it as a string and then declare a pointer on it but a place it is aligned on a 16 byte boundary.
Example

LOCAL _Lvi:LVITEM becomes

LOCAL _Lvi[2 * SIZEOF LVITEM]:BYTE
LOCAL _lpLvi:LPLVITEM

lea rax,_Lvi
and rax,NOT 15
mov _lpLvi,rax

then only use the pointer
That's very fresh, maybe there are errors in my writing.
I read this from AMD - Optimization - 25112.PDF
https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/40332.pdf

TimoVJL

#7
What you need for prolog ?
WinMainCRTStartup proc this is empty prolog
also some align things are solved with right size LOCALs ?

I don't use asm, expect for fun.
May the source be with you

HellOfMice

hi Timo


Or keeping variables into register rather that stack.
I wonder if it would be a good idea to have a structure into which we have the local variables?
What do you think?

Vortex

#9
Hi Philippe,

You could align your structures by calculating their sizes.
Code it... That's all...

Vortex

Code it... That's all...

HellOfMice

#11
Hello and Thank you Vortex,

I have read (quickly) this post and it is the reason I used structures and delared them as a LOCAL variable like this:

STACKPTR_SEARCH_DIRECTORY   STRUCT  8
    lpHeaders           LPPHR_PE_ANALYZER   ?           ;  8
    lpDirectoryAddress  LPSTR               ?           ;  8
    lpszDirectoryName   LPSTR               ?           ;  8
    lpLvi               LPLVITEM            ?           ;  8
    lpszTmp             LPBYTE              ?           ;  8
    lpszVirtualAddress  LPBYTE              ?           ;  8
    lpszVirtualSize     LPBYTE              ?           ;  8
    hListView           HWND                ?           ;  8
STACKPTR_SEARCH_DIRECTORY   ENDS                        ; 64

LPSTACKPTR_SEARCH_DIRECTORY TYPEDEF PTR STACKPTR_SEARCH_DIRECTORY

STACKDATA_SEARCH_DIRECTORY  STRUCT  16
    szTmp               BYTE                128 dup(?)      ; 128
    Lvi                 LVITEM              <>              ;  88
    szVirtualAddress    BYTE                64 dup(?)       ;  64
    szVirtualSize       BYTE                64 dup(?)       ;  64
    dwDirectoryIndex    DWORD               ?               ;   4
STACKDATA_SEARCH_DIRECTORY  ENDS                            ; 348

LPSTACKDATA_SEARCH_DIRECTORY TYPEDEF PTR STACKDATA_SEARCH_DIRECTORY

STACK_SEARCH_DIRECTORY  STRUCT  16
    Data                STACKDATA_SEARCH_DIRECTORY  <>      ; 352
    Pointers            STACKPTR_SEARCH_DIRECTORY   <>      ;  64
STACK_SEARCH_DIRECTORY  ENDS                                ; 416

LPSTACK_SEARCH_DIRECTORY TYPEDEF PTR STACK_SEARCH_DIRECTORY

I hope I have not made errors
Give me your advices and remarks
I use a 16 bye alignment in case I use MMX instructions
I USE ONE STRUCTURE FOR DATAS AND THE OTHERR ONE FOR POINTERS


Philippe

HellOfMice

Rather than using structure I thought to use a buffer and computing a 16 bytesd boundary, when found I declare a structure pointer on that position

Vortex

Hi Philippe,

Your structures are looking OK. Thr most important is to align properly the members of the structures.
Code it... That's all...

Vortex

#14
Hi Philippe,

The quick test below ( excluding the SSE stuff for the moment ) demonstrates that Poasm is successfully aligning the local structures to QWORD boundary.

include LocalStructAlign.inc

PRINTPAGERANGE STRUCT

    nFromPage   dd ?
    nToPage     dd ?

PRINTPAGERANGE ENDS


sample STRUCT

    x           db ?
    y           db ?

sample ENDS

.data

a1  db 'OFFSET var1 = %X',13,10,0
a2  db 'OFFSET var2 = %X',13,10,0
a3  db 'OFFSET ppr  = %X',13,10,0
a4  db 'OFFSET s    = %X',13,10,0
a5  db 'OFFSET var3 = %X',13,10,0

.data?

buffer  db 64 dup(?)

.code

start PROC PARMAREA=4*QWORD

    call    main
    invoke  ExitProcess,0

start ENDP


main PROC PARMAREA=4*QWORD

LOCAL var1:QWORD            ; rsp+50H
LOCAL var2:QWORD            ; rsp+48H

LOCAL ppr:PRINTPAGERANGE    ; rsp+38H
LOCAL s:sample              ; rsp+30H

LOCAL var3:QWORD            ; rsp+28H

    invoke  wsprintf,ADDR buffer,ADDR a1,ADDR var1
    invoke  StdOut,ADDR buffer
   
    invoke  wsprintf,ADDR buffer,ADDR a2,ADDR var2
    invoke  StdOut,ADDR buffer
   
    invoke  wsprintf,ADDR buffer,ADDR a3,ADDR ppr
    invoke  StdOut,ADDR buffer
   
    invoke  wsprintf,ADDR buffer,ADDR a4,ADDR s
    invoke  StdOut,ADDR buffer
   
    invoke  wsprintf,ADDR buffer,ADDR a5,ADDR var3
    invoke  StdOut,ADDR buffer
   
    ret

main ENDP


Output on Windows 7 Sp1 :

OFFSET var1 = 22FC60
OFFSET var2 = 22FC58
OFFSET ppr  = 22FC48
OFFSET s    = 22FC40
OFFSET var3 = 22FC38
Code it... That's all...