Author Topic: MasmBasic  (Read 346719 times)

HSE

  • Member
  • *****
  • Posts: 1744
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #315 on: February 26, 2016, 04:59:04 AM »
The file is open in the correct sheet when the message appear (just to test I saved it open in a different sheet), and later close normally. Perhaps some request format problem (realated with languaje?).

I don't say before but, of course, using the table the screen is magnificent.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #316 on: February 26, 2016, 05:24:34 AM »
If your language is espanol, try using "F2C1:F9C2"
With Portuguese, it should be L2C1:L9C2 (more - look for row and column)

I attach the exe for Spanish.

HSE

  • Member
  • *****
  • Posts: 1744
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #317 on: February 26, 2016, 06:17:13 AM »
Impressive !  :t

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
HeapValidate doesn't find any problems
« Reply #318 on: March 02, 2016, 03:20:09 AM »
Code: [Select]
include \masm32\include\masm32rt.inc
.code
start:
  mov ebx, rv(GetProcessHeap)
  invoke HeapAlloc, ebx, 0, 33
  xchg eax, esi
  mov byte ptr [esi+33], "x"   ; oops!
  invoke HeapValidate, ebx, 0, 0
  print LastError$()
  invoke HeapFree, ebx, 0, esi
  print LastError$()
  exit
end start

So far, so clear: 33 bytes allocated, 33 bytes used (or was it 34 with esi+33? anybody good at math?  ;))
And, as we all expect, LastError$ is 2 x "The operation completed successfully."

However, if you build this snippet with RichMasm, you'll get a different message:
Code: [Select]
## HEAP[DebugHeapTestMasm32.exe]:
## Heap block at 00583F08 modified at 00583F31 past requested size of 21
The operation completed successfully.

## HEAP[DebugHeapTestMasm32.exe]:
## Heap block at 00583F08 modified at 00583F31 past requested size of 21

## HEAP[DebugHeapTestMasm32.exe]:
## Invalid address specified to RtlFreeHeap( 00580000, 00583F10 )
The operation completed successfully.

** DebugHeap found errors **

From version 1 March 2016 onwards, RichMasm will debug console mode applications (and this includes Gui apps built with subsys console, so that's how you can test windows applications).

This feature can be suppressed by inserting OPT_NoDebug somewhere in the code (same for OPT_Wait 0, i.e. don't wait for a keypress). It will also not be used if RichMasm finds an int 3 somewhere in the source, as this will invoke Olly instead.

My tests with timing code from The Laboratory showed no performance differences to non-debugged code.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
MasmBasic update
« Reply #319 on: March 03, 2016, 11:40:45 AM »
Version 3 March 2016:
- DebugHeap now handles the infamous SHBrowseForFolder exception
- If Structured Exception Handling is being used, DebugHeap is off; this was a problem for the SEH example in MbSnippets.asc (the file you see in the middle of the MbGuide welcome screen as "try 90+ snippets")
- Also, when scrolling through the code examples in MbSnippets.asc, the "Init" listbox does no longer lose the focus when you hit F6

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Bug warning
« Reply #320 on: March 09, 2016, 03:58:34 PM »
Recent versions of MasmBasic returned wrong results for the case-insensitive version of StringsDiffer(), with consequences for QSort().
Please reinstall.

The good news is that the new version works correctly, is 40% shorter and 30% faster :biggrin:

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Spreadsheet sorting
« Reply #321 on: March 12, 2016, 02:46:46 PM »
Version 12 March has a new feature - sorting by a column's value:

Quote
; spreadsheet mode - you can sort tab-delimited files by column:
      Recall "MyDataBase.tab", db$(), tab            ; tab = tell Recall it's a tab-delimited file, Excel style
      xchg eax, ecx            ; keep #rows read in ecx
      QSort db$(), 0, [, 0]            ; sort db$(), all rows, by column 3; [optional 0: do not skip the header row]
      QSort db$(), 0, 2003h            ; same but 2000h added: sort using Val() of column 3

This snippet sorts Windows.inc by the value of its equates, regardless if they are expressed as hex or decimal (see e.g. VT_ILLEGAL in the output below):

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  Recall "\Masm32\include\Windows.inc", L$(), tab      ; load file to two-dimensional string array
  QSortMode cis, sls      ; case-insensitive, skip leading spaces
  QSort L$()            ; pre-sort alphabetically
  For_ ecx=0 To eax-1
      .if Instr_(L$(ecx), "equ", 5)      ; 5: 4=full word, 1=case-insensitive
            .Repeat
                  inc eax
                  mov dl, [eax]
            .Until !dl || dl>="0" && dl<="9"      ; e.g. SOMECONSTANT equ <123h>
            .if dl
                  mov byte ptr [eax-1], 9      ; insert a tab to separate string from numerical column
            .endif
      .endif
  Next

  QSort L$(), 0, 2001h, 0      ; sort all rows, 2000h to force MovVal() sort, column 1, 0=don't skip header row
  Store "MyFile.txt", L$()      ; save to file
  Print Str$("%i lines stored, now launching text viewer", L$(?))
  ShEx "MyFile.txt"      ; have a look - search for IMAGE_ORDINAL_FLAG64
EndOfCode


Output:
Code: [Select]
MAXLONGLONG                      equ 7fffffffffffffffh
CLR_NONE         equ 0FFFFFFFFh
ColorsWhite                 EQU 0FFFFFFFFh
FLS_OUT_OF_INDEXES               equ 0FFFFFFFFh
HOVER_DEFAULT   equ 0FFFFFFFFh
INADDR_BROADCAST          equ      0FFFFFFFFh
INADDR_NONE          equ            0FFFFFFFFh
...
VT_ILLEGAL          equ 0ffffh
Yellow                               equ 00FFFFh
UNICODE_STRING_MAX_BYTES         equ 065534
MCI_SEQ_NONE                         equ 65533
WCH_EMBEDDING                    equ 0FFFCh
Green                                equ 00FF00h
...
WS_EX_RIGHTSCROLLBAR                 equ 00000000h
WS_OVERLAPPED                        equ 0h
WSA_WAIT_EVENT_0                 equ ((DWORD 0)
WT_EXECUTEDEFAULT equ 00000000h                           
X3_BTYPE_QP_INST_VAL_POS_X       equ 0
X3_D_WH_SIGN_VAL_POS_X           equ 0
X3_EMPTY_INST_VAL_POS_X          equ 0
X3_IMM20_SIGN_VAL_POS_X          equ 0
...
IMAGE_ORDINAL_FLAG64             equ 8000000000000000h

Since MasmBasic's string sort is stable, the "pre-sort" after Recall() provides alphabetical order for identical values, e.g. for CLR_NONE ... INADDR_NONE in the example above. The numerical sort is not overwhelmingly fast, due to the complexity of Val(), but sorting one Million lines in three seconds looks acceptable IMHO.

Full code attached. Note that in 21 lines you cannot handle the more complex equates 8)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
New Switch_ macro
« Reply #322 on: April 28, 2016, 09:04:26 AM »
include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals someinteger=5      ; for testing a case with a variable
  Init                          ; ## fast switch with jump table ##
  PrintLine "---------------- testing MasmBasic Switch_ ----------------"
  For_ ct=-3 To 20
      m2m ecx, 3
      Print Str$(ct), Tb$

      Switch_ ct
      Case_ -2
            PrintLine "Case -2"
      Case_ 0
            PrintLine "Case NULL"
      Case_ 8, 10, 12, ecx
            PrintLine "Case 8, 10, 12 or ecx"             ; ecx is set to 3
      Case_ someinteger
            PrintLine Str$("Case int var=%i", someinteger) ; case is a variable (or register)
      Case_ 19 : PrintLine "Case 19 (one line)" ; one-liner if only one instruction is needed
      Case_ 15 .. 17
            PrintLine "Case 15 .. 17"
      Default_
            PrintLine "..."
      Endsw_
  Next
EndOfCode


Output:
Code: [Select]
---------------- testing MasmBasic Switch_ ----------------
-3      ...
-2      Case -2
-1      ...
0       Case NULL
1       ...
2       ...
3       Case 8, 10, 12 or ecx
4       ...
5       Case int var=5
6       ...
7       ...
8       Case 8, 10, 12 or ecx
9       ...
10      Case 8, 10, 12 or ecx
11      ...
12      Case 8, 10, 12 or ecx
13      ...
14      ...
15      Case 15 .. 17
16      Case 15 .. 17
17      Case 15 .. 17
18      ...
19      Case 19 (one line)
20      ...

Requires MasmBasic of 28 April 2016, available here. During installation, click on try 90+ snippets to see more examples.

The new Switch_ macro works with Microsoft MASM versions 6.15 ... 10.0 (11 not tested, grateful if somebody can do that...), JWasm, HJWasm and AsmC.

With the exception of the colon-separated one liner, Switch_ is perfectly compatible with the standard Masm32 switch macro. Under the hood, however, it creates a jump table, which makes it faster and shorter.

HSE

  • Member
  • *****
  • Posts: 1744
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #323 on: April 28, 2016, 10:46:31 AM »
Very nice JJ!

Give me a couple of years to study the macros :biggrin:

At first read it's unexpected that I obtain:
 
Code: [Select]
### line 343: case 19 : PrintLine "Case 19 (one line)",13,10 already defined ###

when I was expecting nothing or:
Code: [Select]
     < not possible, use separate line ##>

This is my PrintLine:
Code: [Select]
PrintLine MACRO args:VARARG
  ifb <args>
print
  else
print args, 13,10
  endif
ENDM

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #324 on: April 28, 2016, 05:24:30 PM »
Interesting... you should get "already defined" when a Case_ is already defined, e.g. you have 2x Case 123 (which wouldn't make sense, therefore the forced error).

Would you mind post a complete little example? Thanks.

HSE

  • Member
  • *****
  • Posts: 1744
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #325 on: April 28, 2016, 11:33:15 PM »
Apparently the problem is that the comma of the arguments are interpreted like a multiple case (case_ 10 already exist). 

Case_ 19 : PrintLine "Case 19 (one line)",13,10

With Case_ 19 : PrintLine "Case 19 (one line)",13 ; A Case_ 13 is constructed (see the .exe)

Work perfect with only one argument (and no comma) Case_ 19 : PrintLine "Case 19 (one line)"

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #326 on: April 29, 2016, 12:17:02 AM »
It also works if you move it to the next line as shown below, but anyway, this is a very odd problem. Thanks for flagging this, HSE :icon14:

      Case_ 19
            PrintLine "Case 19 (one line)", 13, 10 ; one-liner if only one instruction is needed

nidud

  • Member
  • *****
  • Posts: 2215
    • https://github.com/nidud/asmc
Re: MasmBasic
« Reply #327 on: April 29, 2016, 12:41:06 AM »
Post deleted per PM request
« Last Edit: May 02, 2016, 03:51:16 AM by nidud »

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Bug is fixed
« Reply #328 on: April 29, 2016, 09:21:13 AM »
*** archive 28 April was temporarily removed - under certain conditions, the Switch_ macro would unbalance the stack ***

But it's fixed now - please reinstall. Sorry for the inconvenience, and thanks again to HSE for informing me about the problem.


jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Improved Switch_ macro
« Reply #329 on: May 06, 2016, 09:25:23 AM »
Please install MB version 6 May 2016:
Inspired by point #2 of a blog post on the merits of Visual Basic, the Switch_ macro can now handle lt and gt:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  PrintLine cfm$("years\tclassification")       ; see #2, VB Case a<b
  For_ ecx=6 To 34 Step 2
      Print Str$(ecx), Tb$

      Switch_ ecx
      Case_ lt 10 :      PrintLine "child"
      Case_ lt 19
            Print "teenie, "

            Switch_ ecx
            Case_ 10..13:      PrintLine "10..13"
            Case_ 14:          PrintLine "14"
            Case_ gt 14:       PrintLine "over 14"
            Endsw_

      Case_ gt 32 :            PrintLine "very old"
      Case_ gt 29, 29 :        PrintLine "old"
      Case_ 24, 26 :           PrintLine "the ideal age"
      Default_
            PrintLine "twen"
      Endsw_
  Next
EndOfCode


Output:
Code: [Select]
years   classification
6       child
8       child
10      teenie, 10..13
12      teenie, 10..13
14      teenie, 14
16      teenie, over 14
18      teenie, over 14
20      twen
22      twen
24      the ideal age
26      the ideal age
28      twen
30      old
32      old
34      very old

Source attached, tested with ML 6.15 and 10.0, JWasm, HJWasm and AsmC.