code segment para 'code'
assume cs:code,ds:code
org 100h
entry: jmp around
func macro p:VARARG
invoke p
exitm <ax>
endm
foo proc
dec ax
ret
foo endp
bar: .if func(foo)
inc ax
.endif
ret
around: mov ax,1
call bar
mov ah,4Ch
int 21h
code ends
end entry
List file from MASM:
0102 foo proc
0102 48 dec ax
0103 C3 ret
0104 foo endp
0104 E8 FFFB * call foo
0107 bar: .if func(foo)
0107 0B C0 * or ax, ax
0109 74 01 * je @C0001
010B 40 inc ax
.endif
010C *@C0001:
010C C3 ret
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> Just some confusion to the fact that you end up behind the label: .if (you put some stuff here).
The "CALL foo" is located before the "bar:" label because expansion is done first. However, if the macro function is a macro argument, the "CALL foo" will be BEHIND the label:
> The "CALL foo" is located before the "bar:" label because expansion is done first. However, if the macro function is a
> macro argument, the "CALL foo" will be BEHIND the label:
Maybe this should be parsed differently?
The bar:.if upcode(expression) is equal to.elesif upcode(expression).
bar: is low-level and .if is high-level, emulating the function:
> I don't think this is an option. The expansion part should match Masm's behavior.
> A deviation must have very good reasons.
The main argument is this: Masm’s behaviour is wrong.
The opportunity is this:
.iffunc(…)
.elseiffunc(…)
.endif
The bar: .if func() is a miner issue, but it should generate a warning, same as using eax in invoke combined with a local address.
The same thing goes for the .elseif func(), since this generates a bug, which is difficult to trace if you’re not familiar with the syntax.
The only place you could expand code here is above the .if statement, so .while func() will not work, but it compile with no problems..
Maybe the high level syntax was created first, and the possibility to expand code later, like the exitm <eax>.
You don’t have to change the expansion part, or create a deviation from Masm’s behaviour, but you should be aware of the places where expansion of code is impossible.
It was my thinking then that this awareness creates an opportunity :-)
The options is then:
- Expand the code and just pretend it’s snowing.
- Generate an error/warning
- Expand the code below the label, above (expression)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That's not feasible because there ARE macro functions that WILL WORK in a .ELSEIF, .WHILE or .UNTIL expressions. It's just that macro functions that generate code lines won't work - and to properly filter these case requires a few hacks.
> - Expand the code below the label, above (expression)
This would also require very ugly hacks. It's a Masm design bug. IMO the best "solution" is not to use macro functions in hll directives. The hll directives can always be replaced by simple code lines. A workaround may be to replace .ELSEIF by .ELSE and .IF.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> This would also require very ugly hacks.
Yes, some real code is required to fix this hack, but it may be feasible.
> It's just that macro functions that generate code lines won't work
It is only these situations that create an opportunity, and the filter should be applied here.
The lll: .hll(..) - in one line – only create problems, so these combinations should not be allowed:
Looks like you're using an old version of jwasm, because since v2.08, ExpandLine() won't return STRING_EXPANDED anymore.
A proper solution will require that .ELSEIF, .WHILE and .UNTIL directives be split in a somewhat "pre-expansion" and a "post-expansion" part. "pre-expansion" is kinda "somewhat", because it can't be called before any expansion, but must be called from inside expansion ( because a possible label in the very same line might require expansion ).
These requirements make the adjustments ultra-ugly. Surely nothing that is to happen for v2.09.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> Looks like you're using an old version of jwasm, because since v2.08, ExpandLine() won't return STRING_EXPANDED anymore.
I tried the v2.08, but none of my project will compile past the first file (se post below).
> A proper solution will require that .ELSEIF, .WHILE and .UNTIL directives be split in a somewhat "pre-expansion" and a "post-expansion" part.
I think the label: macro(..) issue must be fixed first by a PushLabel() function of some kind.
> "pre-expansion" is kinda "somewhat", because it can't be called before any expansion, but must be called from inside expansion ( because a possible label in the very same line might require expansion ).
The label is now removed: expand away.
> These requirements make the adjustments ultra-ugly. Surely nothing that is to happen for v2.09.
If you willing to do anything with this, the first release should at most contain a warning message. If the messages pop up correctly the next step should be an actual fix.
The first fix should be:
label: macro()
label: dec macro()
label: mov edx,macro()
The knowledge you gain from solving this problem could then be applied to the hll section (same issue).
With regards to the inserted function, this only serves as to show what happen if the label-issue is removed.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
code segment para 'code' assume cs:code,ds:code org 100h entry: jmp around func macro p:VARARG invoke p exitm <ax> endm foo proc dec ax ret foo endp bar: .if func(foo) inc ax .endif ret around: mov ax,1 call bar mov ah,4Ch int 21h code ends end entryList file from MASM:
0102 foo proc 0102 48 dec ax 0103 C3 ret 0104 foo endp 0104 E8 FFFB * call foo 0107 bar: .if func(foo) 0107 0B C0 * or ax, ax 0109 74 01 * je @C0001 010B 40 inc ax .endif 010C *@C0001: 010C C3 retO-kay … and what exactly is the problem?
Just some confusion to the fact that you end up behind the label: .if (you put some stuff here)..
> Just some confusion to the fact that you end up behind the label: .if (you put some stuff here).
The "CALL foo" is located before the "bar:" label because expansion is done first. However, if the macro function is a macro argument, the "CALL foo" will be BEHIND the label:
> The "CALL foo" is located before the "bar:" label because expansion is done first. However, if the macro function is a
> macro argument, the "CALL foo" will be BEHIND the label:
Maybe this should be parsed differently?
The bar: .if upcode(expression) is equal to.elesif upcode(expression).
bar: is low-level and .if is high-level, emulating the function:
if (expression) { } elseif (expression) { } else { }A highlevel expression includes upcode like:
if ((fp = fopen(…)) != NULL) {If upcode is allowed, as it is in the .elesif upcode(expression), then this is a bug.
We then have this situation:
The upcode is expanded correctly so it is very close.
> Maybe this should be parsed differently?
I don't think this is an option. The expansion part should match Masm's behavior. A deviation must have very good reasons.
> I don't think this is an option. The expansion part should match Masm's behavior.
> A deviation must have very good reasons.
The main argument is this: Masm’s behaviour is wrong.
The opportunity is this:
The bar: .if func() is a miner issue, but it should generate a warning, same as using eax in invoke combined with a local address.
The same thing goes for the .elseif func(), since this generates a bug, which is difficult to trace if you’re not familiar with the syntax.
The only place you could expand code here is above the .if statement, so .while func() will not work, but it compile with no problems..
Maybe the high level syntax was created first, and the possibility to expand code later, like the exitm <eax>.
You don’t have to change the expansion part, or create a deviation from Masm’s behaviour, but you should be aware of the places where expansion of code is impossible.
It was my thinking then that this awareness creates an opportunity :-)
The options is then:
- Expand the code and just pretend it’s snowing.
- Generate an error/warning
- Expand the code below the label, above (expression)
> - Generate an error/warning
That's not feasible because there ARE macro functions that WILL WORK in a .ELSEIF, .WHILE or .UNTIL expressions. It's just that macro functions that generate code lines won't work - and to properly filter these case requires a few hacks.
> - Expand the code below the label, above (expression)
This would also require very ugly hacks. It's a Masm design bug. IMO the best "solution" is not to use macro functions in hll directives. The hll directives can always be replaced by simple code lines. A workaround may be to replace .ELSEIF by .ELSE and .IF.
> This would also require very ugly hacks.
Yes, some real code is required to fix this hack, but it may be feasible.
> It's just that macro functions that generate code lines won't work
It is only these situations that create an opportunity, and the filter should be applied here.
The lll: .hll(..) - in one line – only create problems, so these combinations should not be allowed:
@@: .if
@@: .elseif
@@: .repeat
@@: .until
@@: .while
…
Then
.if
works and expand code correctly
.break .if
works
.continue .if
works
.elseif
needs a minor label-fixup
.until
should work in theory, but .continue will probably bypass the expanded code.
.while
need some work, code must be expanded below
before this happens
.while func(findfirst)
push eax
invoke findnext
.endw
The main work will be the filter, and then some minor fixup on the expanded code.
So, it requires some work, but it looks possible.
I had a brief look at the expansion of code done in expans.c.
Here is some of the label:
issues. The bold lines fail. [b]l0: dec func(foo) l1: mov edx,func(foo)[/b] l2: .if eax || edx l3: inc eax [b]l4: .elseif func(foo)[/b] l5: dec eax l6: .endif [b]l7: .while func(foo) l8: .continue[/b] l9: .break lA: .endw lB: .repeat [b]lC: .continue[/b] lD: .break lF: .until func(foo) l2 is one exception here, and I assume the label is pushed before code creation. The ones that fail include code expansion. The exception in this case is (token == label && token->next == directiv && ...) A general rule on a higher level could be this: if (token == label && next token is on the same line) PushLabel() ... PushMacro() I don't know how to do this, but I created a function to test the output. This was inserted in the function ExpandLine(..) [code] i = (tokenarray[1].token == T_COLON || tokenarray[1].token == T_DBL_COLON); if (Token_Count > 2 && i) { char *p,b[MAX_LINE_LEN]; strcpy(b, tokenarray[0].string_ptr); strcat(b, tokenarray[1].string_ptr); p = string + strlen(b); *p++ = 0; while (*p == ' ') p++; AddLineQueue(p); AddTokens(tokenarray, 0, 2-Token_Count); return( STRING_EXPANDED ); } [/code] Result: [code] 00000001 l0: 00000001 1 invoke foo 00000001 E8FAFFFFFF *1 call foo 00000006 48 dec eax 00000007 l1: 00000007 1 invoke foo 00000007 E8F4FFFFFF *1 call foo 0000000C 8BD0 mov edx,eax 0000000E l2: 0000000E .if eax || edx 0000000E 23C0 * and eax , eax 00000010 7504 * jnz @C0002 00000012 * @C0003: 00000012 23D2 * and edx, edx 00000014 7408 * jz @C0001 00000016 * @C0002: 00000016 l3: 00000016 40 inc eax 00000017 l4: 00000017 1 invoke foo 00000017 E8E4FFFFFF *1 call foo 0000001C .elseif eax 0000001C EB05 * jmp @C0004 0000001E * @C0001: 0000001E 23C0 * and eax, eax 00000020 7401 * jz @C0005 00000022 l5: 00000022 48 dec eax 00000023 l6: 00000023 .endif 00000023 * @C0005: 00000023 * @C0004: 00000023 l7: 00000023 1 invoke foo 00000023 E8D8FFFFFF *1 call foo 00000028 .while eax 00000028 EB04 * jmp @C0006 0000002A * @C0007: 0000002A l8: 0000002A .continue 0000002A EB02 * jmp @C0006 0000002C l9: 0000002C .break 0000002C EB04 * jmp @C0008 0000002E lA: 0000002E .endw 0000002E * @C0006: 0000002E 23C0 * and eax, eax 00000030 75F8 * jnz @C0007 00000032 * @C0008: 00000032 lB: 00000032 .repeat 00000032 * @C000A: 00000032 lC: 00000032 .continue 00000032 EB07 * jmp @C0009 00000034 lD: 00000034 .break 00000034 EB09 * jmp @C000B 00000036 lF: 00000036 1 invoke foo 00000036 E8C5FFFFFF *1 call foo 0000003B .until eax 0000003B * @C0009: 0000003B 23C0 * and eax, eax 0000003D 74F3 * jz @C000A 0000003F * @C000B: [/code]Looks like you're using an old version of jwasm, because since v2.08, ExpandLine() won't return STRING_EXPANDED anymore.
A proper solution will require that .ELSEIF, .WHILE and .UNTIL directives be split in a somewhat "pre-expansion" and a "post-expansion" part. "pre-expansion" is kinda "somewhat", because it can't be called before any expansion, but must be called from inside expansion ( because a possible label in the very same line might require expansion ).
These requirements make the adjustments ultra-ugly. Surely nothing that is to happen for v2.09.
> Looks like you're using an old version of jwasm, because since v2.08, ExpandLine() won't return STRING_EXPANDED anymore.
I tried the v2.08, but none of my project will compile past the first file (se post below).
> A proper solution will require that .ELSEIF, .WHILE and .UNTIL directives be split in a somewhat "pre-expansion" and a "post-expansion" part.
I think the label: macro(..) issue must be fixed first by a PushLabel() function of some kind.
> "pre-expansion" is kinda "somewhat", because it can't be called before any expansion, but must be called from inside expansion ( because a possible label in the very same line might require expansion ).
The label is now removed: expand away.
> These requirements make the adjustments ultra-ugly. Surely nothing that is to happen for v2.09.
If you willing to do anything with this, the first release should at most contain a warning message. If the messages pop up correctly the next step should be an actual fix.
The first fix should be:
label: macro()
label: dec macro()
label: mov edx,macro()
The knowledge you gain from solving this problem could then be applied to the hll section (same issue).
With regards to the inserted function, this only serves as to show what happen if the label-issue is removed.