Author Topic: High Level Language in MASM  (Read 55821 times)

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
High Level Language in MASM
« on: November 13, 2012, 02:33:57 AM »
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
Code: [Select]
label: mov edx,func(strlen,string)expands to
Code: [Select]
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):

Code: [Select]
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.

Code: [Select]
<expanded expression>
jmp expression
statement:
<statement>
expression:
<expression>
jnz statement

Code: [Select]
if (<expression1>) { <statement1> }
else if (<expression2>) { <statement2> }

This will currently fail if <expression2> is expanded.

Code: [Select]
<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
Code: [Select]
label: .if func(strlen,string)To
Code: [Select]
label:
.if func(strlen,string)

Expansion of <expression> must be delayed and expanded correctly.

Code: [Select]
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:
Code: [Select]
;.while func(foo) - delay expansion
* jmp expression
* statement:
<statement>
The exit code will be called when .endw if found, an this expands as follows:
Code: [Select]
* 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:
Code: [Select]
* 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.

Code: [Select]
<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:
Code: [Select]
.if ((ecx = strlen(string)) > edi)

jj2007

  • Member
  • *****
  • Posts: 7541
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #1 on: November 13, 2012, 02:58:16 AM »
The .untilcxz now use dec ecx, jnz label and not loop.

Caution with the flags - this might break some existing code.

include \masm32\MasmBasic\MasmBasic.inc   ; download
   Init
   mov ecx, 5
   mov eax, -3
   .Repeat
      inc eax
   .Untilcxz   ; old version
   .if Zero?
      Print Str$("ZERO:   \teax=%i", eax)
   .else
      Print Str$("Non-Zero:\teax=%i", eax)
   .endif
   Print Str$(", ecx=%i\n", ecx)

   mov ecx, 5
   mov eax, -3
   .Repeat
      inc eax
      dec ecx   ; new version
   .Until Zero?
   .if Zero?
      Print Str$("ZERO:   \teax=%i", eax)
   .else
      Print Str$("Non-Zero:\teax=%i", eax)
   .endif
   Print Str$(", ecx=%i", ecx)
   Inkey
   Exit
end start

qWord

  • Member
  • *****
  • Posts: 1454
  • The base type of a type is the type itself
    • SmplMath macros
Re: High Level Language in MASM
« Reply #2 on: November 13, 2012, 03:05:39 AM »
Why are you talking about MASM? You have made an syntax extension to JWASM thus it allows code that isn't compatible with MASM.

EDIT: you may add an option to disable the extension, because existing code that relies on that special expansion behavior won't work anymore.
MREAL macros - when you need floating point arithmetic while assembling!

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #3 on: November 13, 2012, 03:59:47 AM »
Why are you talking about MASM?
The HLL syntax was introduced by MASM, not JWASM.
The problems addressed here is MASM syntax.

You have made an syntax extension to JWASM thus it allows code that isn't compatible with MASM.
True, as mention in text.

JJ, I see the first one, but:
Quote from:  jj2007
.Until Zero?
I'll do some testing.

What is the output from the original test now?

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #4 on: November 13, 2012, 04:21:51 AM »
Code: [Select]
.386
.model flat

.code

mov ecx, 5
mov eax, -3
.repeat
inc eax
dec ecx ; new version
.until ZERO?

end
expands to:
Code: [Select]
MOV ECX,00000005h
MOV EAX,FFFFFFFDh
CS000A: INC EAX
DEC ECX
JNZ SHORT CS000A
Code: [Select]
.386
.model flat

.code

mov eax, -3
.repeat
inc eax
.until ZERO?

end
expands to:
Code: [Select]
MOV EAX,FFFFFFFDh
CS0005: INC EAX
JNZ SHORT CS0005

jj2007

  • Member
  • *****
  • Posts: 7541
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #5 on: November 13, 2012, 05:20:15 AM »
Here are the results for ML, JWasm standard and JWasm Nidud:

(RichMasm: Press F6 to assemble & link
opt_xxx in uppercase, last one is valid)

OPT_Assembler   ml
Non-Zero:       eax=2, ecx=0
ZERO:           eax=2, ecx=0

OPT_Assembler   JWasm
Non-Zero:       eax=2, ecx=0
ZERO:           eax=2, ecx=0

OPT_Assembler   JWasmNidud
ZERO:           eax=2, ecx=0
ZERO:           eax=2, ecx=0


Admittedly .Untilcxz is an exotic instruction nowadays. The only reason why somebody would use it is to keep the flags intact. And that is exactly what your version will break.

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #6 on: November 13, 2012, 06:10:08 AM »
Quote
Admittedly .Untilcxz is an exotic instruction nowadays. The only reason why somebody would use it is to keep the flags intact. And that is exactly what your version will break.
This is a minor issue in my view, and I change this behaviour to make it less exotic.
The next step will be to allow value, like .repeat (ecx = 5, eax = -3).
The syntax should be based on logic, and .untilcxz expands to: Until (E)CX is ZERO.
I always assumed this returned ZERO:
Code: [Select]
    .repeat
call item_SetIndex?
.break .if !ZERO?
sub edi,SIZE S_TOBJ
    .untilcxz
    .if ZERO?

Now the code works as it should do. Make sense?

Searching the masm32 directory for .untilcxz gives no result.
In the MASM directory there is many, but none who assume flags on return.

Special case (forcing a flag return):
Code: [Select]
.REPEAT
...
.UNTILCXZ (al != ' ')    ; Scan for last nonblank character
.IF     !zero?  ; If nonblank char found,

Code: [Select]
JWasm v2.08b, Nov 12 2012
00000000 .repeat
00000000     *   @C0002:
00000000 .untilcxz (al != ' ')
00000000     *   @C0001:
00000000  3C20      *   cmp al , ' '
00000002  E1FC      *   loopz  @C0002
00000004     *   @C0003:

Code: [Select]
JWasm v2.09pre, Sep 22 2012
00000000 .repeat
00000000     *   @C0002:
00000000 .untilcxz (al != ' ')
00000000     *   @C0001:
00000000  3C20      *   cmp al , ' '
00000002  E1FC      *   loopz  @C0002
00000004     *   @C0003:

Code: [Select]
Microsoft (R) Macro Assembler
.repeat
 00000000    *@C0001:
.untilcxz (al != ' ')
 00000000  3C 20    *     cmp    al, ' '
 00000002  E1 FC    *     loope  @C0001

The test I was curious about is this:

Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc   ; download
  Init
  Let esi="This is a stupid test"
  .if Instr_(esi, "stuupid")
     PrintLine "stuupid found"
  .elseif Instr_(esi, "test")
     PrintLine "test found"
  .endif
  Inkey "Found something??", CrLf$
  .if Instr_(esi, "stuupid")
     PrintLine "stuupid found"
  .else
     .if Instr_(esi, "test")
  PrintLine "test found"
     .endif
  .endif
  Inkey "better??"
  Exit
end start

jj2007

  • Member
  • *****
  • Posts: 7541
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #7 on: November 13, 2012, 06:37:14 AM »
This is a minor issue in my view, and I change this behaviour to make it less exotic.
Those few coders who have ever used .Untilcxz will be eternally grateful that you broke their exotic code. All others don't need this "improvement".

Quote
The test I was curious about...

That test works fine now, compliments :t

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #8 on: November 13, 2012, 08:08:08 AM »
Quote
Those few coders who have ever used .Untilcxz will be eternally grateful that you broke their exotic code.

These modifications will be Public Domain, free for all use or not.
All modifications will be defined in the global.h header file, which at the moment look like this:
Code: [Select]
#define __FULLSRCPATH /* Use full or relative path (as given) fix */
#define __FIXLABELS /* label: func(foo) fix */
#define __EXPANDHLL /* expand .elsif and .while func(foo) fix */
/*
 * none-masm compatible updates (include fix for -Zg)
 */
#define __UNTILCXZ /* replace <loop> with <dec ecx, jnz> */
#define __TESTREGREG /* replace <and/or reg,reg> with <test reg,reg> */

Quote
All others don't need this "improvement".
The aim here is to explore the possibility to implement HLL in assembly, so the loops included are definitely needed for this to become a reality. If this is bad news for a minority "exotic coders", so be it. I think the reason for this (that nobody use it) is the way it’s currently implemented. So I changed it for this reason.

But the main reason I implemented this is (of course) that I use it myself, and if some find it useful, new features and #defines would have been added, but so far this seems not to be the case.

jj2007

  • Member
  • *****
  • Posts: 7541
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #9 on: November 13, 2012, 09:26:39 AM »
The aim here is to explore the possibility to implement HLL in assembly, so the loops included are definitely needed for this to become a reality. If this is bad news for a minority "exotic coders", so be it.

Nidud,

There is no need to "improve" exotic code like...
   .Repeat
      inc eax
   .Untilcxz eax==edx

... since you can simple use the less exotic
   .Repeat
      inc eax
      dec ecx
      .Break .if Zero?
   .Until eax==edx

... or, better...

   .Repeat
      inc eax
      dec ecx
   .Until Zero? || eax==edx


No problem for new code. But it is fatal to change the behaviour of an assembler or compiler when your audience are sitting on a pile of old code. I have thousands of assembler sources, and I am pretty sure that none contains .Untilcxz, but some older members here may have such code. When you introduce such "improvements", the verdict is "not compatible, bug-prone, don't touch".

Believe me, those who watch this thread do watch it with sympathy. I cannot speak for qWord, but I am just trying to tell you that your efforts into .Untilcxz are not well invested :icon14:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 4806
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: High Level Language in MASM
« Reply #10 on: November 13, 2012, 10:34:32 AM »
Yep,

Any of the instructions that utilise ancient junk like j***cxz and higher level variants were abandoned long ago (486 era) because they are so slow. Coding the loop counter can be done with any register, not just ECX and it can be done much faster than with an antique instruction.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #11 on: November 13, 2012, 10:57:04 AM »
Quote
There is no need to "improve" exotic code like...
   .Repeat
      inc eax
   .Untilcxz eax!=edx
Agreed, and no improvement has been made there, compiles equal to MASM.

Quote
No problem for new code. But it is fatal to change the behaviour of an assembler or compiler when your audience are sitting on a pile of old code.
It’s not fatal, and the change does not break with any documentation given by MS. They don’t say anything about flags.

http://msdn.microsoft.com/en-us/library/ty7cf4bk(v=vs.71).aspx

Quote
I have thousands of assembler sources, and I am pretty sure that none contains .Untilcxz,
And the reason for this is?
My reason will be speed: loop is slow.
The reason for using it will be readability.

Quote
but some older members here may have such code.
If so, I really want to know.

Quote
When you introduce such "improvements", the verdict is "not compatible, bug-prone, don't touch".

There are many things in JWASM that is different from MASM, hence the reason for the switch –Zg, which in this case works.


habran

  • Member
  • *****
  • Posts: 1107
    • uasm
Re: High Level Language in MASM
« Reply #12 on: November 13, 2012, 12:43:19 PM »
Hey nidud,
don't get discouraged in your innovations :idea: :eusa_clap:
even though I have opinion that you are barking up to wrong tree here
none here wants to make a step forward and have to face a new, 'evil' things :eusa_naughty:
it is mush safer to hold on old, safe-proof stuff, who cares about wrinkles
it spells "conservatism" 
but, hey, that is why we cling to assembler :biggrin:
 
best regards
Cod-Father

japheth

  • Guest
Re: High Level Language in MASM
« Reply #13 on: November 13, 2012, 10:15:50 PM »

nidud, I like your enthusiasm.

As for me, however, I'm one of those guys who don't believe in progress.  Calling me "conservative" would be an euphemism, I'm deep 19th century.

Therefore I'm very reluctant to accept "extensions" for jwasm. Perhaps you should consider to start a fork, with it's own name ( nwasm? ).


habran

  • Member
  • *****
  • Posts: 1107
    • uasm
Re: High Level Language in MASM
« Reply #14 on: November 14, 2012, 12:13:48 AM »
Hey japheth,
Code: [Select]
As for me, however, I'm one of those guys who don't believe in progress.
how dare you to say that!!!  :icon_eek:
You created JWasm, the best thing in long time of assembly programming!!! :bgrin:

would you call that REGRESS??? ::)

would you call that regress to WASM???

However, I appreciate your decisions about the things you will accept or refuse to include in your JWasm
The source is available and everyone who wants something else can start a new fork

best regards 

Cod-Father