Author Topic: MasmBasic  (Read 142789 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7541
  • Assembler is fun ;-)
    • MasmBasic
GDI+
« Reply #315 on: February 25, 2016, 02:21:07 PM »
First MasmBasic update this year features some improvements under the hood, plus new GdiPlus functions, see screenshot below and attached executable. The source is in \Masm32\MasmBasic\Res\GuiPieExcel.asc; inter alia, there is a conditional flag allowing to extract the data for the pie straight from M$ Excel.
« Last Edit: February 25, 2016, 08:23:51 PM by jj2007 »

HSE

  • Member
  • ****
  • Posts: 530
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #316 on: February 26, 2016, 02:45:02 AM »
Why Read R1C1:R6C2 notprocessed?

Grincheux

  • Member
  • ***
  • Posts: 328
  • Never be pleased, Always improve
    • Asm for fun
Re: MasmBasic
« Reply #317 on: February 26, 2016, 03:27:43 AM »
It is not MasmBasic but RichBasic :badgrin:
Kenavo (Bye)
----------------------
Asm for Fun
My Links
"La garde meurt mais ne rend pas"
Cambronne à Waterloo

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7541
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #318 on: February 26, 2016, 03:36:57 AM »
Why Read R1C1:R6C2 notprocessed?

No idea. The request is StringToArray xlsRead$("R2C1:R9C2"), x$(), tab, and it works fine with my versions of Excel, i.e. Office 2003 and Office Starter 2010.

If you see this error string, it means you arrived at the connected state; which implies that the communication to Excel is working in principle.

If you comment out the xlsClose command, what do you see in Excel? Does Excel open the file?

If the Excel part is not interesting for you, here is an alternative:

  if 1                        ; 1 for testing, 0=use Excel to read from file
      ; Data "Asset      percent"            ; no header row
      Data "Gold      20"
      Data "Stocks      15"
      Data "Bonds      35"
      Data "ETFs      15"
      Data "Options      7.5"
      Data "Cash      7.5"
      Read x$(tab)      ; create and read a dynamic array of tab-delimited strings
  else
      xlsConnect            ; no args=System
      .if !Zero?              ; errors are returned via the Zero? flag
            xlsOpen esi            ; example from C++
            .if !Zero?
                  xlsConnect "PieData"            ; tell Excel to which sheet you want to talk
                  .if !Zero?
                        StringToArray xlsRead$("R2C1:R9C2"), x$(), tab
                  .endif
                  ; xlsClose
                  xlsDisconnect
            .endif
      .endif
  endif
« Last Edit: February 26, 2016, 04:49:20 AM by jj2007 »

HSE

  • Member
  • ****
  • Posts: 530
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #319 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: 7541
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #320 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: 530
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #321 on: February 26, 2016, 06:17:13 AM »
Impressive !  :t

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7541
  • Assembler is fun ;-)
    • MasmBasic
HeapValidate doesn't find any problems
« Reply #322 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: 7541
  • Assembler is fun ;-)
    • MasmBasic
MasmBasic update
« Reply #323 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: 7541
  • Assembler is fun ;-)
    • MasmBasic
Bug warning
« Reply #324 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: 7541
  • Assembler is fun ;-)
    • MasmBasic
Spreadsheet sorting
« Reply #325 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: 7541
  • Assembler is fun ;-)
    • MasmBasic
New Switch_ macro
« Reply #326 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: 530
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #327 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: 7541
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #328 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: 530
  • <AMD>< 7-32>
Re: MasmBasic
« Reply #329 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)"