flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > New .if/.else/.loop Approach |
Author |
|
Picnic 18 Jan 2012, 12:35
Hi uart777,
Can you give a usage example of .loop macro because i'm having an illegal instruction error. |
|||
18 Jan 2012, 12:35 |
|
uart777 18 Jan 2012, 16:22
Oh, sorry. Edited. Replaced let i=x with push x, pop i. It was written this way to support all memory operands as in: .loop [a]=[b] to [c]
; an example with my code... include 'z.inc' integer i=0 text t(32), f='Value: %n/%hh/%bb' code .loop [i]=0 to 3 print t, f, [i], [i], [i] MessageBoxA 0, t, t, 0 ; no invoke needed with my code .endl ; < remember, .endl for .loop exit |
|||
18 Jan 2012, 16:22 |
|
Picnic 19 Jan 2012, 00:05
Well it's nice.
I did a small modification tο adjust the loop counter properly. Code: macro .loop [c] { local ..start, ..end define ?s 0 match i==x =to n, c \{ define ?s 1 push x ; let i=x pop i ..start: ?START equ ..start ?END equ ..end ?INDEX equ i ?LIMIT equ n \} if ?s eq 0 ERROR: 'Incorrect loop syntax' end if } macro .endl { mov ecx, ?INDEX cmp ecx, ?LIMIT je ?END inc ?INDEX ; i++ jmp ?START ; continue ?END: restore ?START, ?END, ?INDEX, ?LIMIT } |
|||
19 Jan 2012, 00:05 |
|
uart777 24 Jan 2012, 03:24
Thanks. Nothing is wrong with the index/counter. I have tested .if/.else/.loop extensively, even used them to create useful programs like art/image editors and mini dis/assemblers.
However, I just noticed that .break and .continue do NOT WORK properly. They jmp to the beginning or end of ANY recent HL block including if. To correct this, each HL block must have a distinctive begin and end (?BEGIN.IF, ?BEGIN.LOOP, etc) or there must be separate versions of break/continue (.breakl, .breakw). Otherwise, something like this will not work: .loop [i]=0 to [variables.n] array.index variables, [i] let eax=&[?variable.name+eax] .if.text.equal [token], eax .break ; error: jmps to .if start, not .loop jmp @f ; < use this instead .end .endl @@: |
|||
24 Jan 2012, 03:24 |
|
Picnic 24 Jan 2012, 07:13
uart777 wrote: Thanks. Nothing is wrong with the index/counter. I have tested .if/.else/.loop extensively, even used them to create useful programs like art/image editors and mini dis/assemblers. Oh, forgive my carelessness uart777. It was late at night. |
|||
24 Jan 2012, 07:13 |
|
Overflowz 24 Jan 2012, 11:19
Hi uart777, I'm not fimilar with macro and can you post that macro, where we can use API calls without invoke ? Thank you.
|
|||
24 Jan 2012, 11:19 |
|
uart777 25 Jan 2012, 04:58
Hi, Overflowz. I have custom "library; import" macros that construct
the PE import table manually (db x) and define the name itself as a macro which calls it from the ITA. Thus, no "invoke"-like prefix and automatic error checking on number of parameters. To understand this, check out my command/"proc/edure" file: Code: ; $$$$$$$$$$$$$$ Z77 ASM LIBRARY $$$$$$$$$$$$$$$$$ ; ************** SUNGOD SOFTWARE ***************** ; ???????????????? COMMAND.INC ??????????????????? ; push parameters forwards or backwards macro pushf [p] { ; push parameters forward common if ~ p eq forward pushd p common end if } macro pushr [p] { ; push parameters backwards common ; to access forwards if ~p eq reverse pushd p common end if } ; call a/ddress direct or p/ointer indirect macro calla a, [p] { common pushr p call a } macro callp c, [p] { common calla [c], p } ; call direct with "variable arguments" (...) ; then push invisible # parameters last ; (TEXT>print t, f, ... uses this convention) macro callv c, [p] { common ?n=1 reverse pushd p ?n=?n+1 common push ?n call c add esp, ?n*4 } ; call cdecl direct (or indirect if [c]) macro cdecl c, [p] { common ?n=0 reverse pushd p ?n=?n+1 common call c add esp, ?n*4 } ; call DirectX "interface" macro callx c, x, [p] { common pushr p ; push parameters mov eax, [c] push eax ; push class address mov eax, [eax] call dword [eax+x] ; call c+m } macro callfp f { ; call function pointer cmp dword [f], 0 ; if defined jz @f calla dword [f] @@: } ;;;;;;;;;;;;;;;;;;;; COMMAND ;;;;;;;;;;;;;;;;;;;; ; create "function/proc/edure" macro command name, [p] { common ; only insert this inside of the executable ; if it was used somewhere if used !#name !#name: ; real command !name ; macro to call with no callp/"invoke" prefix. ; example: f a, b, c macro name p \{ pushr p call !#name \} !#name.$type='c' ?begin equ !#name ?parameters equ p ..n.parameters=0 ..n.locals=0 ..locals.size=0 ; create parameter names and offsets if ~ p eq ; if parameters virtual at ebp+8 forward local ..p ..p dd ? ; (ebp++i*4 p equ ..p ..n.parameters=..n.parameters+1 common end virtual push ebp ; create stack frame mov ebp, esp end if ; ... } ; HL return statement. use this instead of ; ret/n in HL commands. no ret/urn before endc. ; it inserts one automatically macro return v { common if ~ v eq ; value? mov eax, v end if if ..n.parameters<>0 ; if parameters leave ret ..n.parameters*4 ; ret n else if ..n.locals<>0 ; if locals leave ret else ret end if } ; end command macro endc { return .$=$-?begin ; total size if ..n.parameters<>0 ; if parameters match p, ?parameters \{ restore p, ?begin \} end if if ..n.locals<>0 ; if locals match l, local.names \{ restore l \} end if ; ... end if ; end "if used name" at very beginning } ; locals ... - create local 32BIT variables. ; example: locals x, y, n, c macro locals [p] { common local.names equ p forward ..n.locals=..n.locals+1 common ..locals.size=..n.locals*4 virtual at ebp-..locals.size forward local ..l ..l dd ? p equ ..l common end virtual if ..n.parameters=0 push ebp ; create stack frame mov ebp, esp end if sub esp, ..locals.size ; "allocate" locals } ; localz ... - same but initialize locals; ; for local pointers that re/allocate ; memory or structures that should have ; 0/default values macro localz [p] { common locals p push edi mov edi, esp xor eax, eax mov ecx, (..locals.size shr 2) rep stosd pop edi } Example usage: Code: ; draw "bitmap"; 2D pixel array command draw.bitmap, pixels, x, y, w, h, key, alpha locals p, i, iw visible [x], [y], [w], [h] ; invisible? return fail .r let eax=[pixels], [p]=eax,\ ; p=pixels ecx=[w], ecx<<2, [iw]=ecx ; image w in bytes .loop [i]=0 to [h] let eax=[y], eax+[i] draw.scanline [p], [x], eax, [w],\ [key], [alpha] let eax=[iw], [p]+eax .endl .r: endc Now, to call this, just write its name and parameters (no "invoke"-like prefix): draw.bitmap [p], [x], [y], [w], [h], [key], [alpha] - SUNGOD SOFTWARE |
|||
25 Jan 2012, 04:58 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.