Masm32 SDK description, downloads and other helpful links

Main Menu


Started by jj2007, May 23, 2012, 10:16:07 PM

Previous topic - Next topic


Version 22 June 2016 features some improvements of the RichMasm editor (see here), plus one new LineCount() macro and an improvement of PopCount().

LineCount - pretty fast, see timings
      mov ecx, LineCount(pBuffer)                ; count carriage returns (Ascii 13, 0Dh)
      mov ecx, LineCount(pBuffer, 1000)          ; count CRs in the first 1000 bytes of the buffer
      mov ecx, LineCount(pBuffer, 1000, lf)      ; count linefeeds (Ascii 10, 0Ah)
      mov ecx, LineCount(pBuffer, 1000, "a")     ; count the char a
Rem   - returns DWORD in eax
      - use instead of EM_EXLINEFROMCHAR (which returns wrapped lines, not very useful for coding)

The new PopCount() allows limiting the count to 16 or 8 bits (this is not documented in MbGuide.rtf; note that PopCount() runs on all CPUs and is almost as fast as the native popcnt instruction that you may find on recent CPUs):

include \masm32\MasmBasic\      ; download

  mov ebx, 88888888h
  PrintLine Str$("In ebx, %i bits are set: ", PopCount(ebx)), Bin$(ebx)
  mov ebx, 8888h
  Print Str$("In bx, %i bits are set\n", PopCount(16:ebx))
  mov ebx, 88h
  Print Str$("In bl, %i bits are set\n\n", PopCount(8:ebx))

  mov esi, cfm$("\nThis\nstring\nhas\nplenty\nof\nlines,\nbut\ncounting\nthem\nis\neasy")
  Inkey "The string", esi, Str$("\nhas %i lines", LineCount(esi))


In ebx, 8 bits are set: 10001000100010001000100010001000
In bx, 4 bits are set
In bl, 2 bits are set

The string
has 11 lines


MasmBasic version 30 June has some improvements under the hood. Attached is a proof of concept for an "interpreter" - launch it, and edit the prefilled text.

Other changes regard the editor. A new option:
OPT_Cls 0 ; 0=do not clear the console when building a new version

Default remains "clear the console when building".


Inspired by the A close to authodox API Window thread, MasmBasic and RichMasm can now build 64-bit sources - example attached.

Inter alia, Vasily Sotnikov's includes and libs are required in \Masm64\Include and \Masm64\Lib
Plus, you need \Masm64\bin\ml64.exe etc

Note that the attached *.asc file, which opens in RichMasm, is the complete project. The resource file is built "on the fly", see the two red Rsrc at the end, while the x64 xml file is now included in the MasmBasic package. The icon files in \Masm32\MasmBasic\icons work fine with x64 8)

One of RichMasm's nice features is that an int 3 triggers the debugger when building a project. This works now with the x64 debugger, too. See the WM_CLOSE message for an example.


MasmBasic update of 17 July 2016 has two new templates for "dual 32/64 building". The OPT_64 switch determines which version to use. A standard Masm32 installation is enough, no additional libraries required.

Here is the simpler console version:

include \Masm32\MasmBasic\Res\
; ### simple console demo, assembles in 32- or 64-bit mode with ML64, AsmC, JWasm, HJWasm ###
  Print "This code was assembled with "      ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  Print Chr$(@AsmUsed$(1))
  ifidn @Environ(o64), <1>
      Print Chr$(" in 64-bit format", 13, 10)
      Print Chr$(" in 32-bit format", 13, 10)
  Print "Print Str$(123), CrLf: "
  if 0
      Print Str$(123), 13, 10      ; not possible
      PrintLine Str$(123)      ; much better ;-)
  Print "Type a number: "
  mov rsi, Input$()
  Print Str$("The value of your number is %i\n", Val(rsi))
  Print "64-bit assembly is easy, it seems..."

; activate your favourite debugger by eliminating the x, then insert int 3 somewhere in your code and hit F6
OxPT_DebPath   \Masm64\arkdasm\arkDasm.exe
OxPT_DebPath   \Masm64\x64Dbg\release\x64\x64dbg.exe

Current macros available for 64-bit code (the absolute minimum for the usual homework request...):
jinvoke apiarg, args:VARARG
rv FuncName:REQ,args:VARARG
repargA rarg
Chr$ any_text:VARARG
Hex$ arg
Str$ sform$, sNum0:VARARG
Val arg$
Print args
PrintLine args


Side-by-side assembly ;)

(in CreateWindowEx, the @64 variable sets the x coordinate to a different position)


Update 6 August features Inkey and deb macros for 64-bit code - see menu File/New Masm code:
Dual 32/64 bit console/GUI   templates that compile both as 64 and 32-bit applications


Minor update 8 August: SetListBox got more options; default options are fast but produce more code. Standard example:

include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyLb, "listbox", y 60, h 940
  GuiControl MyEd, "static", text "Double-click to open a file - Дважды щелкните, чтобы открыть файл", h 50
  GetFiles *.as?|*.rc      ; asc, asm, rc
  SortFiles                ; show latest files on top
  SetListbox Files$()      ; Fill the listbox with UTF-8 encoded file names
  Event Command
  .if NotifyCode==LBN_DBLCLK
      uShEx LbSel$         ; open selected file with ShellExecuteW (u=assume UTF-8 for LbSel$)

For a speed test, see


Update 15 August:
- SetListbox may now take a callback function to decide if a string in a given array should be added
- Under menu File/New Masm source, a new template "controls" was added, inter alia with a SetListBox example


Update 30 August:

- more complete dual 64/32 bit include files (no external libraries required)

- GetHash function:

include \masm32\MasmBasic\
      Let esi=FileRead$("\Masm32\qEditor.exe")
      .if GetHash(esi, LastFileSize, sha)     ; FileRead$ sets LastFileSize, also for binary files
            PrintLine "The SHA of qEditor.exe is   ", Tb$, Hex$(xmm0), " ", Hex$(ecx)
            PrintLine "Hashing failed: ", Err$()
      void GetHash(esi, LastFileSize)
      mov ecx, edx                              ; fifth word returned in edx
      Print "Fast MD5 of qEditor.exe is ", Tb$, Hex$(xmm0), CrLf$
      GetHashRev=1                              ; use official MD5 byte order
      .if GetHash(FileRead$("\Masm32\qEditor.exe"))   ; MD5, len of string will be calculated
            PrintLine "qEditor, byte order MD5 specs: ", Tb$, Hex$(xmm0)

- returns success (1) or failure (0) in eax
- four dwords are returned in xmm0
- in case of SHA, the fifth dword will be in edx
- results can be displayed as a Hex$(xmm0), plus Hex$(edx) for SHA. The byte order will be reversed, compared to
  online hash calculators. You may use GetHashRev=1 to follow the MD5 specs, but more code will be generated
- with only one para, GetHash calculates the length; this is meaningful only for text files


Attention, the 64-bit examples in version 30 August choked in Win10. Fixed for version 31 August - my apologies :redface:


Version 10 September 2016 sees one major change: Instead of JWasm, the RichMasm IDE will now install HJWasm32 if it can't find it in \Masm32\bin

You can test this feature by
- renaming \Masm32\bin\HJWasm32.exe to HJWasm32_old.exe
- during MasmBasic installation, hitting F6 while the help file is shown

Feedback welcome - and thanks a lot to Habran and Johnsa for their hard work :t


Version 20 September 2016 introduces two new macros, Alloc16 and Free16:

include \masm32\MasmBasic\      ; download
      Dim PtrSSE() As DWORD
      For_ ct=0 To A16Max-1      ; 100 aligned pointers
            Alloc16 Rand(10000)
            mov PtrSSE(ct), eax
            Print Hex$(al), " "
      For_ ct=0 To A16Max-1
            Free16 PtrSSE(ct)
Rem      for use with SSE instructions that require 16-bit alignment

Typical output:F0 D0 B0 B0 80 30 50 00 D0 D0 10 20 70 10 90 70 40 50 70 60 B0 B0 30 20 00 30 90 00 50 20 A0 30 E0 10 F0 20 B0 80 F0 50 E0 70 00 90 C0 F0 10 F0 50 E0 90 60 A0 20 A0 20 F0
C0 40 C0 50 A0 B0 20 E0 30 80 70 B0 A0 30 C0 50 B0 00 20 D0 F0 10 80 A0 A0 B0 10 A0 C0 70 10 20 F0 50 D0 B0 40 80 90 D0 B0 D0 60


Update 10 October 2016: The MasmBasic Switch_ macro is now also available for dual 64-/32-bit builds (see menu File/New Masm source/Dual 32/64 bit console/GUI templates, and the RichMasm screenshot below). The source builds as 32- or 64-bit code with ML.exe, HJWasm (default) or AsmC. No other libraries required, just a valid Masm32 installation plus MasmBasic.

Other minor additions:

mcs      multiple commands - see example in the message loop below
      mcs mov eax, 100 : add eax, 30 : sub eax, 7: deb 4, "sum:", eax : Inkey "-- press any key --"
      mcs mov eax, 100 : add eax, 30 : sub eax, 7: <Print Str$("result: eax=%i\n", eax)>
Rem      - mcs allows to put several commands on one line, separated by a colon as in Basic
      - if macros depend on previous commands, like e.g. Str$(...), <put them in brackets>

xmov      extended mov
      xmov MyR8, 123456.7890123456      ; assign a double directly
      xmov MyR4, MyR8      ; mem to mem, different operand size
      xmov someSQ, someSD
      xmov someSD, someSQ
      xmov ct, -5
      xmov MyR4, 32767
Rem      - use if in doubt about the best way to shove a value into a memory location (check the disassembly)
      - works with MasmBasic and 64-/32-bit JBasic

      jinvoke MyTest, &v0, *v1, addr v2, offset v3, &v4, v5
Rem      - jinvoke is a macro that works like invoke but assembles with 32- and 64-bit code alike


Version 4 November 2016 is available :icon_cool:

New features:

a) GuiImage learned to care for resources, Unicode and the Internet (see attached for an example using resources; no temp files 8)):

include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
  ; args are imgsrc$ or resource ID, optional: no args=upper left corner, original size, x=fit: use full canvas, or x, y [, w, h]
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit                  ; use full canvas
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", 50, 400, 160, 900   ; use specific x, y, w, h
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", 50, 200            ; use x, y, original w, h
  GuiImage "\Masm32\MasmBasic\Res\FileOpen.png", 100, 7, 40, 40      ; use specific x, y, w, h
  GuiImage "\Masm32\MasmBasic\Res\MasmLogo.png"                  ; upper left corner, original size
  GuiImage ";attach=6;type=avatar", 7, 7
  GuiImage "Это тест.jpg", fit     ; Unicode is allowed
  GuiImage wCL$(), 315, 7          ; also via the commandline
  GuiImage 125, 84, 7, 70, 70      ; 125 is a RC_DATA resource ID (IDs must be 48...127)
  GuiImage Files$(ecx), 238, 7, 70, 70                  ; you can dynamically load images

b) MemState for identifying leaks, e.g. in the Paint event:

GuiParas equ "Hello Masm32 Forum", x400, y100, w250, h300
include \masm32\MasmBasic\Res\MbGui.asm
SetGlobals imgCt
void Split$("Hutch\nDednDave\nErol\nqWord\nrrr314159\nSteve\nMarinus\nBaltoro\nYves\njj2007", "\n", name$())
Event Key
  .if wParam==VK_LEFT && imgCt>48
      dec imgCt
  .elseif wParam==VK_RIGHT && imgCt<57
      inc imgCt

Event Paint
  If_ imgCt==0 Then add imgCt, 48
  MemState("WorkingSetSize, abs delta: %__i ", abs delta)
  GuiImage imgCt, fit
  GuiTextBox 7, 99.9-25, 80, 18, name$(imgCt-48)


In Avatar.exe, when you hit the right key to advance in the list of images, changes in memory use will be printed to the console (see \Masm32\MasmBasic\MbGuide.rtf for all MemState() options):
WorkingSetSize, abs delta: 3392 2840
WorkingSetSize, abs delta: 3524 132
WorkingSetSize, abs delta: 3636 112
WorkingSetSize, abs delta: 3572 -64
WorkingSetSize, abs delta: 3620 48
WorkingSetSize, abs delta: 4008 388
WorkingSetSize, abs delta: 4020 12

c) SysLink control implemented:

GuiParas equ "SysLink demo", w600, h400, ICC_LINK_CLASS      ; title, height, classes needed
include \masm32\MasmBasic\Res\MbGui.asm            ; this include file ships with MasmBasic
GuiControl MySysLink, "SysLink", FileRead$("")
Event Command
  If_ NotifyCode==NM_CLICK Then wShEx Link$()            ; open link in browser


Update 7 November (download):

The GuiImage function got two companions: GuiImageCallback and SaveImageToFile:
include \masm32\MasmBasic\Res\MbGui.asm ; simple foto viewer, allows rotation without changing the time stamp
  GuiImageCallback RotateOrSave
  SetGlobals rotatemode, savemode, imgCt, maxCt ; *** use at your own risk, test with less valuable photos! ***
  GetFiles wCL ; translate commandline to Files$() array
  dec eax
  mov maxCt, eax
Event Key
  mov ecx, maxCt
  .if wParam==VK_LEFT && imgCt>0
dec imgCt
  .elseif wParam==VK_RIGHT && imgCt<ecx
inc imgCt
  .elseif wParam==VK_R && rotatemode<=7
.if Zero?
and rotatemode, 0 ; 7->0
inc rotatemode
  .elseif wParam==VK_L
dec rotatemode
.if Sign?
m2m rotatemode, 3 ; 0->3
  .elseif wParam==VK_S
dec savemode ; save image
  GuiCls ; trigger the Paint event
Event Paint
  mov ecx, Files$(imgCt)
  SetWin$ hWnd=Mid$(ecx, Rinstr(ecx, "\")+1))+" - ImageViewer"
  GuiImage ecx, fit
EndOfEvents ; v v v user-defined callback function v v v
  gdi+ GdipImageRotateFlip, gicbObj, rotatemode ; gicb stands for GuiImageCallBackObject
  .if savemode
Clr savemode, rotatemode
SaveImageToFile wFiles$(imgCt)

Full project attached. Tested on Win10, Win7-64 and XP, but use at your own risk. Make a backup of your marriage photos first 8)

Btw, in contrast to the behaviour of the Windows image viewer, this proggie will keep the timestamp after rotation. Use the left and right arrow keys to scroll through the photos, use the l and r keys to rotate and flip images. If you build it yourself, you may use the s key to save the rotated image.

If you see GetLastError, incorrect parameter, it just means that you didn't drag any images over the exe. You can also open a DOS prompt in the exe's folder and paste ImageViewAndRotate.exe;attach=6;type=avatar :eusa_dance: