There is an attempt to include HLL in MASM, but it is currently not fully implemented. The first problem with the current implementation is that it doesn’t work, and the second problem is that it's not High Level Language.
Analysing the problem
All expansions are pre-processed by the assembler, and this is line-based. The code label: mov edx,func(strlen,string)
expands to invoke strlen,string
label: mov edx,eax
This creates problems for the HLL section so this must be addressed first.
Syntax (.while, .if and .elseif):
while (<expression>) { <statement> }
<statement> is executed repeatedly as long as the value of <expression> remains non-zero. This will currently fail if <expression> is expanded.
<expanded expression>
jmp expression
statement:
<statement>
expression:
<expression>
jnz statement
if (<expression1>) { <statement1> }
else if (<expression2>) { <statement2> }
This will currently fail if <expression2> is expanded.
<expanded expression1>
expression1:
<expression1>
jz expression2
<statement1>
[color=red]<expanded expression2>[/color]
jmp endif
expression2:
<expression2>
jz endif
<statement2>
endif:
Fixing the problem
All labels must be corrected to the actual offset of the code.
From label: .if func(strlen,string)
To label:
.if func(strlen,string)
Expansion of <expression> must be delayed and expanded correctly.
jmp expression
statement:
<statement>
expression:
<expanded expression>
<expression>
jnz statement
A late expansion of a macro is difficult but possible. It dos however need a full rescan of the source for each pass, so the level of impact to the existing code becomes a huge undertaking. It will also have an impact on the speed of the compilation, so expansion should be done in the first pass to avoid messing up the existing logic.
The problem is not to move the expansion to the right place, but to find a way to split the fixup of labels in the exit code.
Pass one:
;.while func(foo) - delay expansion
* jmp expression
* statement:
<statement>
The exit code will be called when .endw if found, an this expands as follows:
* expression:
* test eax,eax
* jnz statement
It’s not possible to move the expansion without braking up the code, so whatever approach used this must be done:
* expression:
<expanded expression>
* test eax,eax
* jnz statement
So the label must be inserted in pass one, and removed in the next passes. The same approach also applie to the .elseif expansion.
<expanded expression1>
<expression1>
jz expression2
<statement1>
jmp endif
expression2:
<expanded expression2>
<expression2>
jz endif
<statement2>
endif:
A test case is made to see if this work as expected. It passes the regression test provided with jwasm v2.08, but no effort has been made to fix the listing, which is destroyed in this process.
In addition to these updates there is also a few non-MASM changes made to this release:
The and/or eax,eax test is replaced by test eax,eax.
The .untilcxz now use dec ecx, jnz label and not loop.
TODO:
To implement a full high level syntax in <expression> also means that assignment of value (as done by habran in the .for loop) and invoke is included:
.if ((ecx = strlen(string)) > edi)