BASIC is the Best Approach to Simple and Intelligent Coding. MasmBasic is a library that allows to use BASIC syntax in assembler, i.e. it is not a "separate" language but rather a library of macros and routines, fully compatible with the latest Masm32 SDK (version 11) (http://masm32.com/), MASM (http://www.microsoft.com/downloads/en/details.aspx?familyid=7a1c9da0-0510-44a2-b042-7ef370530c64&displaylang=en) (version 6.15 or higher) and UAsm (http://www.terraspace.co.uk/uasm.html), and thoroughly tested on Windows XP, 7, 8 and 10.
While MasmBasic is pretty stable (and pretty fast - typically twice as fast as C), it is still Assembler, therefore the usual disclaimers apply - do not use for military purposes, in hospitals and anywhere else where buggy applications could cause damage. You have been warned :cool:
To install the library, double-click SetupMasmBasic.exe in the attached archive (see step-by-step instructions (https://www.jj2007.eu/Masm32_Tips_Tricks_and_Traps.htm)).
Note that some AntiVirus programmes don't like it - see Latest batch of unsound AV scanners (http://masm32.com/board/index.php?topic=10591.0) for reasons.
For an overview of the over 500 powerful available functions, see \Masm32\MasmBasic\MbGuide.rtf (after extracting the archive, of course) or see the (incomplete) MasmBasic Quick Reference (http://www.jj2007.eu/MasmBasicQuickReference.htm) online. See also A guide to the RichMasm editor (http://masm32.com/board/index.php?topic=5314.0).
28 April 2024: Updated archive attached below, now with ultrafast HexVal(), OpenAdo, ZipFiles, Json$(), RichMasm support for the Masm64 SDK, SetWatch, StackWalk, StringBuild, FastMath, Say "Hello World", ArrayIndex(array, match), _Local x$="Hello World", better UTF-8 support (http://masm32.com/board/index.php?topic=6231.msg72181#msg72181), MemState for finding leaks, MapView control (http://masm32.com/board/index.php?topic=6631.msg71093#msg71093), Math symbols in RichMasm, PrintRtf, dual 32/64-bit examples in File/New Masm source menu, and a 64-bit version of the deb macro (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019). Older changes: For_ each x$ in My$(), improved Switch_ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1285); GetFiles (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1056) returns UTF8 now; WebCam, GetProcessArray(), new GSL lib, Choose, fast MemSet, Instr_() and Sinus() added, GuiTextBox improved. Data and Read , float counters are valid in For_ ... Next, and xmm regs are preserved for all MasmBasic commands. Note that simple Windows API calls can trash them on 64-bit versions of Windows.
Latest additions: GuiXX functions, Split$, Join$, Filter$, commandline to Files$(), GfCallback, true Unicode, also in file I/O; UnzipFile, ArraySet, SetReg64 for 64-bit registry settings, ArrayMerge, Age(), GetRegArrays, unsigned LONGLONG in Str$(), ShEx, xls interface (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1085), ArraySet (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1128), ArrayPlot (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1182), AddWin$, WritePipe, Plugins, IsFolder(), wOpen, FileOpen$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1031)/FileSave$, also as Unicode versions, Extract$, Dialogs (http://masm32.com/board/index.php?topic=697.0), COM support (CoInvoke, GuidsEqual(), IUnknown, VARIANT, ...), improved ANSI and Unicode commandline macros CL$()/wCL$(), improved xHelp (http://masm32.com/board/index.php?topic=463.msg4190#msg4190), Launch$(), Try/Catch/Finally, ...
Installation hints for Windows 8 ... 10 (on Win7 & XP it's simpler):
- click on SetupMasmBasicDayMonthYear.zip below
- depending on your browser and zip application, choose open in xyZip or Save as...
- if it doesn't open in 7-zip or WinZip or whatever, locate the zip file and open it
- once you see SetupMasmBasic.exe, open it (double-click or select and Enter)
- you should see an extraction dialog, and shortly after a box "Windows Protected Your PC - Windows SmartScreen prevented..."
- do NOT click OK; instead, click on the tiny green link "More info"
- you will see Program SetupMasmBasic.exe and "unknown publisher"; click "Run Anyway"
- the screen will darken, and you see a box "Do you want to allow .. changes to your computer?"
- type the administrator password and click Yes
- you should see now a big box "MasmBasic - a fast library..." with a EULA; read it, then click "Accept & Install"
** if anything goes wrong, have a look at our AV Software sh*t list subforum (http://masm32.com/board/index.php?board=23.0), then disable your antivirus for the \Masm32 folder and try again; if that doesn't help, reply to this thread **
Various extras, JBasic for dual 64-/32-bit assembly (https://masm32.com/board/index.php?topic=9266.0)
The attached JBasic (SetupJBasic*.zip) builds on your existing Masm32 and MasmBasic installation. Just run the JBasic*.exe installer.
-------- Maps in MasmBasic: --------
In the RichMasm editor, click on File/New Masm source to see a green box with code templates.
Two of them called Gdi+ and maps (in the middle to the right) require a map of Europe. Extract the two files in the attachment to \Masm32\MasmBasic\Res\europe.* to make these templates work.
(http://www.webalice.it/jj2006/pics/MbSnippets.png)
This snippet (a full-fledged Windows console application :biggrin:) produces the following output:
Введите строку, которую вы хотите найти в папке \Masm32\Include: bitmap
#1 \Masm32\Examples\advanced\wrep\result.asm
#2 LOCAL tbab :TBADDBITMAP
#3 \Masm32\Examples\advanced\wrep\richedit.asm
#4 LOCAL tbab :TBADDBITMAP
#5 \Masm32\Examples\Bill_Cravener\calender\calendar.asm
...
#96 \Masm32\Examples\exampl02\appack\toolbar.asm
#97 LOCAL tbab :TBADDBITMAP
#98 ; The toolbar bitmap
#99 ; You must supply a bitmap for the toolbar that ha
#100 \Masm32\Examples\exampl02\appack\rsrc.rc
ok
As the example shows,
1. MasmBasic is not BASIC: No BASIC dialect understands mov ebx, 400
2. MasmBasic is assembly, i.e. it will flawlessly assemble with Microsoft Macro Assembler (MASM, version 6.15 upwards) or, better, with Jwasm (http://www.japheth.de/JWasm.html)
Here is a more complex application. It opens Windows.inc, converts all hexadecimal equates into decimal ones, and writes it back to disk:
include \masm32\MasmBasic\MasmBasic.inc
Init
call Convert
Exit
Convert proc
LOCAL pos, posAfter, MyTimer, MyCounter
and MyCounter, 0
mov MyTimer, Timer
Recall "\Masm32\include\Windows.inc", L$() ; load an array of strings from file
mov ebx, eax
For_ n=0 To ebx-1
mov pos, Instr_(1, L$(n), "equ", 5) ; start in pos 1, 1=case-insensitive + 4=full word
.if pos
mov esi, Val(Mid$(L$(n), pos+3, 99)) ; get the numeric value of the string behind equ
.if signed edx<0 ; edx returns the number of usable chars; a
neg edx ; negative number indicates a hex$ or bin$ was found
add edx, pos
add edx, 3
mov posAfter, edx
inc MyCounter
Let L$(n)=Left$(L$(n), pos-1)+"EQU "+Str$(esi)+Mid$(L$(n), posAfter)
.endif
.endif
Next
Store "MyWindows.inc", L$() ; write all strings back to file
sub MyTimer, Timer
Print Str$("\nConverting %i hex equates in Windows.inc to decimals", MyCounter), Str$(" took %i ms\n", 0-MyTimer)
ret
Convert endp
end start
Output:
Converting 7676 hex equates in Windows.inc to decimals took 31 ms
MasmBasic comes with RichMasm (http://www.masmforum.com/board/index.php?topic=9044.0). The editor is configured to give context-sensitive help with the F1 key, and to expand many instructions. For example,
opo [space] will expand to Open "O", #1,
mb becomes MsgBox 0, "¨", "Hi", MB_OK
for_ becomes For_ n=0 To ebx-1 ... Next
ism becomes invoke SendMessage,
etc.; more in \masm32\MasmBasic\MbGuide.rtf (in RichMasm: File/MasmBasic Guide)
Last but not least an ultra-short Win32 application ;)
include \masm32\MasmBasic\MasmBasic.inc
Init
Credits
Exit
end start
Let me know who is missing :biggrin:
I wrote this library for my own use and pleasure, but since many forum members contributed to it, through good advice and even better algos, I think it is just fair to release it here. Thanks to everybody :icon14:
For the xHelp project, I had to add a few functions - sorry if you tried to assemble xHelp.asc with the June version. Among others, these features have been included:
Launch$
Init
; the line below launches Arc.exe with option v and returns what SdtOut produces:
Let esi=Launch$(ExpandEnv$(Chr$(34, "%ProgramFiles%\FreeArc\bin\Arc.exe", 34, " v Lib32.arc"))) ; see FreeArc (http://freearc.org/download/testing/FreeArc-0.67-alpha-sources.tar.bz2)
StringToArray esi, FreeArc$() ; translate linear output to an array
For_ ebx=0 To eax-1
PrintLine Str$(ebx), Tb$, FreeArc$(ebx)
Next
Rem args as in Launch above; returns string in eax
Output:
0 FreeArc 0.666 listing archive: Lib32.arc
1 Listing archive: Lib32.arc
2 Date/time Attr Size Packed CRC Filename
3 ----------------------------------------------------------------------
4 2000-06-02 16:24:14 ....... 1364 10002 c2249beb Masm32\m32lib\a2dw.asm
5 2004-05-21 07:38:48 ....... 3399 0 50c16759 Masm32\m32lib\a2dw_ex.asm
...
41 2003-12-06 08:43:10 ....... 4843 1097 b83a653e Masm32\m32lib\ascdump.asm
42 ----------------------------------------------------------------------
43 38 files, 77,396 bytes, 11,099 compressed
ExeFromWin$
Let esi="Recent Unread Topics"
Print esi, " was launched by ", ExeFromWin$(WinByTitle(esi)) ; by firefox.exe, of course ;-)
Rem returns full path of executable that created a window
SetGlobals ; declares global variables relative to ebx, syntax as in LOCAL
.data?
whatever dd ?
SetGlobals hMain, hStatic, hEdit
SetGlobals hMenu, hM1, hM2, rc:RECT
SetGlobals msg:MSG, wc:WNDCLASSEX, exeBuffer[MAX_PATH]:BYTE, gBuffer[1024]:BYTE
.code
; no args: set ebx to the right offset; must be used in Init part and all callbacks (WndProc, SubEdit, ...)
SetGlobals
Rem variables return [ebx+x]
Enum ; create a list of IDs
Enum IdMenuNew, IdMenuSave, IdMenuCopy, IdTimer
Enum 20:IdEdit, IdButton1, 30:IdButton2, IdStatic, IdFind, IdFindStatic
Rem - variables return [ebx+x]
- default start is 10, but different start values can be specified
Version 14 September features two new macros for use with COM, GuidFromString and GuidsEqual.
I hope the sample below is self-explanatory for the COM fans ;-)
.code
CLSID_WebBrowser GuidFromString(8856F961-340A-11D0-A96B-00C04FD705A2) ; ExDisp.h (http://%programfiles%\microsoft%20sdks\windows\v7.0a\include\exdisp.h)
IID_IWebBrowser2 GuidFromString(D30C1661-CDAF-11D0-8A3E-00C04FC9E26E) ; OleIdl.h (http://%programfiles%\microsoft%20sdks\windows\v7.0a\include\oleidl.h)
IID_IUnknown GuidFromString(00000000-0000-0000-C000-000000000046)
IID_IOleObject GuidFromString(00000112-0000-0000-C000-000000000046) ; MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683922%28v=vs.85%29.aspx)
IID_IOleClientSite GuidFromString(00000118-0000-0000-C000-000000000046)
IID_IOleWindow GuidFromString(00000114-0000-0000-C000-000000000046)
IID_IOleInPlaceSite GuidFromString(00000119-0000-0000-C000-000000000046)
MyQuery proc pRefID, pRet
xor edx, edx
.if GuidsEqual(pRefID, IID_IUnknown)
mov edx, pWB2 ; return this
.else
.if GuidsEqual(pRefID, IID_IOleClientSite)
mov edx, MyClientSite ; return ptr to a handler
.else
.if GuidsEqual(pRefID, IID_IOleWindow)
mov edx, MySite
.else
.if GuidsEqual(pRefID, IID_IOleInPlaceSite)
mov edx, MySite
.endif
.endif
.endif
.endif
mov eax, pRet
mov [eax], edx ; return result
xor eax, eax ; S_OK
.if !edx
mov eax, E_NOINTERFACE ; flag failure
.endif
ret
MyQuery endp
Versions earlier than 19 Sept had a problem with Declare, it's fixed now:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masmforum.com/~masm32/board/index.php?topic=94)
Init ; initialise the app
Dll "shimgvw" ; load the shell image view dll aka Windows Picture and Fax Viewer Library
Declare ImageView_Fullscreen, 4 ; ImageView_Fullscreen expects 4 dwords
void ImageView_Fullscreen(0, 0, wCL$(1), SW_SHOW) ; we need the wide version of the commandline arg
Err$(0) ; there is no retval, so we have to test for errors
Exit ; do a clean exit, inter alia FreeLibrary
end start
I seized the occasion to tune up the dialog examples. Here is a nice one:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0) (version 19 Sept 2012)
Init
Let ecx=NoTag$(FileRead$("http://masm32.com/why.htm")) ; get some wise words from the World Wide Web
DlgDefine "... but nothing beats Basic, hehe:", 0, 0, 325, 90
DlgControl dcStatic, "\Masm32\examples\exampl04\car\car.jpg", SS_BITMAP, 80, 5 ; any Masm32 installation has this JPG
DlgControl dcStatic, "\masm32\RichMasm\icons\Smiley.ico", SS_ICON, 30, 1 ; x, y [, width, height]
Let ecx="... "+Mid$(ecx, Instr_(ecx, "and contrary"), 109)
DlgControl dcStatic, wChr$(ecx), SS_LEFT, 5, 18, 70, 70 ; x, y, width, height
DlgShow
Exit
end start
Full source and exe attached ;)
Extract$ extracts a substring based on left and right matches
; simple example:
Let esi='This is a link to <a href="http://www.google.com">Google</a> that can be extracted'
Print "The URL for ", Extract$(esi, Chr$(34, 62), "</a>"), " is " ; 34, 62 = ">
Inkey Extract$(esi, "http://", Chr$(34), xsIncL) ; you could use '"' (single/double/single quote) instead of Chr$(34)
; result: The URL for Google is http://www.google.com
; syntax: Extract$(pSrc, "left match" [, "right match"] [, xsFlags] [, maxlines*)] [, startIndex])
; right match: if omitted, end of line is assumed
; xsFlags: if omitted, search for left match is case-sensitive, left and right matches are excluded
; maxlines: default is 1, i.e. right match must be in same line; for extracting structures etc, put a reasonable value, e.g. 100
; startIndex: default is 1, i.e. beginning of string; if xsLoop is set, search for the left match restarts where the last right match
was found; see also the options for Instr_ - Extract$ uses Instr_ for the left match
xsCaseI ; case-insensitive search for left match (right: always case-sensitive)
xsIs ; intellisense; search is case-insensitive for 1st char only, i.e. Hello = hello
xsI1c ; ignore 1st char in left match, e.g. ?:\Masm32\...
xsFullW ; full word (left match only)
xsIncL ; include left pattern (e.g. http://)
xsIncR ; include right pattern
xsExcL ; exclude left pattern, e.g. {url= ... }
xsExcR ; exclude right pattern
xsTrimL ; trim left side, i.e. strip everything <=ASCII 39 aka single quote
xsTrimR ; trim right side (after excluding right match if xsExcL is set)
xsTrim=xsTrimL or xsTrimR ; trim both sides
xsLineL ; include line of the left match
xsLineR ; include rest of line after the right match (must include right match...)
xsLoop ; let Instr_ start behind the last position, for using in loops
*) if the right pattern contains a linefeed (LF, Ascii 10), the maxlines counter will never stop the pattern search
----------------------------------------------------------
The last flag, xsLoop, is used in the following demo, a Windows console application that extracts
all structures from the two main Masm32 include files. Do not use the result for work, as there are
problems with nested structures (e.g. unions ending with ends) and some structures ending with
lowercase ends.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
; First, let's get some useful source string:
Let ecx=FileRead$("\Masm32\include\Windows.inc")+FileRead$("\Masm32\include\WinExtra.inc")
Open "O", #1, "Structures.txt" ; open a file for output
xor ebx, ebx ; reset counter
.While 1
inc ebx
.Break .if !Extract$(ecx, "STRUCT", 'ENDS', xsFullW or xsLineL or xsIncR or xsLoop, 100)
Print #1, eax, CrLf$
.Endw
Close #1 ; file #1 closed
Inkey Str$("%i structures found\n", ebx)
Exit
end start
Rem - Extract$ returns pointer in eax, and len of result in edx
- can be used with Print and Let even if no match found, i.e. eax=0; in this case, Extract$ will print as ?
RichMasm Key ex$
As a complement to MasmBasic's new file dialog understanding Unicode file names,
I added the capacity to use these file names for opening files:
wOpen "O", #1, wRes$(ResID) ; file name from a resource string, e.g. Добро пожаловать.txu
... wPrint to this file ...
.if wFileOpen$("Unicode text=*.txu")
wPrint wCrLf$, "You selected ", wFileOpen$(), wCrLf$
wOpen "I", #1, wFileOpen$() ; use the filename
lea ecx, [Lof(#1)-2] ; required: length of file minus 2 bytes BOM
Let esi=New$(ecx) ; create a string with the required length
Input #1, esi, 2 ; discard the Unicode BOM
Input #1, esi, ecx ; read rest of file into buffer
Close
wPrint "The content of the selected file: [", esi, "]", wCrLf$
; the console may have problems with Chinese etc, a MessageBox shouldn't:
wMsgBox 0, esi, "The content of the selected file:"
.endif
Version 4 October is available on top of this thread. Full example in \masm32\RichMasm\Res\SkelFileIO_Unicode.asc - open in RichMasm and hit F6.
Version 14 October 2012 has some improvements under the hood, inter alia regarding JWasm compatibility and handling of more data types for ebx-relative global variables. Here is an example, a more complete one will be in \masm32\RichMasm\SetGlobalsQword.asc after extracting the MasmBasic archive.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals MyR4:REAL4, MyR8:REAL8, MyR10:REAL10, MyPoint:POINT, MyQ:QWORD
SetGlobals MySD:SDWORD, MyD, MyW:WORD, MyB:BYTE, MyRect:RECT
Init
SetGlobals ; short code through ebx-relative addressing
MovVal MyB, "123"
MovVal MyW, "12345"
MovVal MySD, "-123456789" ; signed dword
MovVal MyD, "123456789" ; both versions work
mov MyD, Val("123456789") ; Val is for DWORD destinations only
MovVal MyR4, "12345.6789"
MovVal MyR8, "123456789012345678"
MovVal MyR10, "12345678901234567890"
MovVal MyQ, "123456789012345678"
MovVal xmm0, "123456789012345678"
MovVal f:xmm1, "123456789012345678"
MovVal MyPoint.y, "987654321" ; structure elements
mov MyPoint.x, Val("123456789") ; Val is for DWORD destinations only
MovVal MyRect.left, "111111111"
mov MyRect.bottom, Val("999999999")
deb 4, "SetGlobals", MyB, MyW, MyD, MySD, MyQ, MyR4, MyR8, MyR10, xmm0, f:xmm1
deb 4, "POINT & RECT", MyPoint.x, MyPoint.y, MyRect.left, MyRect.bottom
Inkey
Exit
end start
Output:
SetGlobals
MyB 123
MyW 12345
MyD 123456789
MySD -123456789
MyQ 123456789012345678
MyR4 12345.68
MyR8 1.234567890123457e+17
MyR10 1.23456789012345679e+19
xmm0 123456789012345678
f:xmm1 1.234567890123457e+17
POINT & RECT
MyPoint.x 123456789
MyPoint.y 987654321
MyRect.left 111111111
MyRect.bottom 999999999
Update 30 October 2012 (attached to 1st post above):
- RichMasm editor has learned to warn the user when doing stupid things (http://masm32.com/board/index.php?topic=844.msg7270#msg7270)
- Launch$("proggie.exe") has been enhanced with ExitCode():
Let My$=Launch$("GetInfo.exe") ; imagine a little proggie that writes something useful to console ...
mov eax, ExitCode() ; ... and finishes with a Yes/No/Cancel MsgBox plus invoke ExitProcess, eax
.if eax==IDYES
... do something with My$ ...
.endif
Rem - returns a global variable containing the para passed with ExitProcess, i.e. the DOS-style errorlevel
- for Launch "whatever", this value is also returned in edx
Hi jj,
Does MB supports nested for loop?
Example:
include \masm32\MasmBasic\MasmBasic.inc
Init
For_ ebx=1 To 3
For_ ecx=1 To (4-ebx)
Print Str$(edx," ")
Next
Print CrLf$
Next
Exit
end start
I tried to assemble using jwasm and ML. Both failed.
jwasm
Quote
JWasm v2.09pre, Oct 29 2012, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
forloop.asm(6) : Error A2227: Missing right parenthesis in expression
MbFor(46)[MasmBasic.inc]: Macro called from
forloop.asm(6): Main line code
forloop.asm(6) : Error A2227: Missing right parenthesis in expression
MbFor(60)[MasmBasic.inc]: Macro called from
forloop.asm(6): Main line code
forloop.asm(6) : Error A2209: Syntax error: )
MbFor(74)[MasmBasic.inc]: Macro called from
forloop.asm(6): Main line code
invalid Str$
forloop.asm: 14 lines, 1 passes, 109 ms, 0 warnings, 3 errors
ML
Quote
Microsoft (R) Macro Assembler Version 11.00.50522.1
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: forloop.asm
forloop.asm(6) : error A2006:undefined symbol : atVt
MbFor(49): Macro Called From
forloop.asm(6): Main Line Code
invalid Str$
forloop.asm(7) : error A2207:missing right parenthesis in expression
MbFor(3): Macro Called From
forloop.asm(6): Main Line Code
forloop.asm(7) : error A2207:missing right parenthesis in expression
MbFor(10): Macro Called From
forloop.asm(6): Main Line Code
forloop.asm(7) : error A2208:missing left parenthesis in expression
MbFor(11): Macro Called From
forloop.asm(6): Main Line Code
forloop.asm(7) : error A2052:forced error
Str$(3): Macro Called From
Print(0): Macro Called From
forloop.asm(7): Main Line Code
Quote from: anta40 on November 04, 2012, 03:24:43 AM
Hi jj,
Does MB supports nested for loop?
Example:
include \masm32\MasmBasic\MasmBasic.inc
Init
For_ ebx=1 To 3
For_ ecx=1 To (4-ebx)
Print Str$(edx," ")
Next
Print CrLf$
Next
Exit
end start
Hi Anta,
No brackets for 4-ebx, and Str$() has a different syntax (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1167):
For_ ebx=1 To 3
For_ ecx=1 To 4-ebx
Print Str$(ecx), " "
Next
Print CrLf$
Next
Ah, a small typo :redface:
Thanks jj, now it works as expected :t
Great ;-)
Version 5 Nov 2012 is out:
- FileOpen$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030)() keeps user's folder changes
- IsFolder() macro
- Dll & Declare speedup: see example here (http://masm32.com/board/index.php?topic=815.msg7655#msg7655)
Hi jj.
MasmBasic is really a nice project. If I had enough knowledge I'd started
a similar project myself. Unfortunately I'm not able to do much with it for the time
being.
It remains, however, one of my goal to learn and use some MasmBasic as soon
as I've enough capacity to do it.
Carry on this optimal work.
Frank
Thanks a lot, Frank.
Version 3 December features an improved xHelp, now included in the MasmBasic package.
Inter alia, xHelp has learned how to add F1 context-sensitive help to qEditor. After extraction of the package (the archive in post #1 of this thread (http://masm32.com/board/index.php?topic=94.msg264#msg264)) with "use folder names", launch \Masm32\InstallXhelp.exe. Afterwards, you can select some text, e.g. CreateWindowEx in qEditor, and press F1. Compliments to Hutch who made such a great plugin interface for the Masm32 editor :t
And apologies that I stole the idea to create a plugin interface for RichMasm, too - PM me for details ;-)
One lesson a day keeps the teacher away [somehow] :lol:
The only thing I really miss for an extension of MASM32 like
MasmBasic is a tutorial to learn step by step the use of the
MACROS library and routines.
Probably some help can be found in the editor and in the
examples, but a Tutorial is always welcome. :t
Changes in the update of 26.12.2012 (attached to first post, details in \Masm32\MasmBasic\MbGuide.rtf):
AddWin$
AddWin$ hEdit=CrLf$+"[one line more]" ; append some text to an edit control
; this line appends the current date and time to an edit control:
AddWin$ hEdit=CrLf$+"["+Trim$(Launch$("cmd.exe /C date /T"))+", "+Trim$(Launch$("cmd.exe /C time /T"))+"]"
WritePipe
Launch "cmd.exe /C time", SW_RESTORE, cb:hEdit ; launch an app that requires console input; show its output in the edit control
WritePipe "20:40:50" ; set the time
; you may add a 0 as second argument if you don't want a CrLf sequence to be appended:
WritePipe esi, 0 ; write zero-delimited string in esi, do not append CrLf
Rem will show an error message if the pipe was closed for some reason
Jochen,
it seems you've done a great effort for the new update. Did you burn the midnight oil?
Gunther
Quote from: Gunther on January 03, 2013, 12:00:20 AM
it seems you've done a great effort for the new update. Did you burn the midnight oil?
Yes I did, Gunther - but I just fixed a "midnight bug". Launch$() returns output from a console proggie, but it is not designed for proggies that expect
input, and it choked badly when I tried. Version 2 Jan
b behaves better, it just returns La$? to indicate an error.
----
Changes in the update of 2 Jan 2013 concern the handling of pipes in Launch (more in \masm32\MasmBasic\MbGuide.rtf):
dec ready2load ; set the "we launched a process" flag
Launch esi, SW_MINIMIZE, cb:hOutput ; cb: = we want to see the output
...
CASE WM_TIMER
.if ready2load ; flag "we launched a process"
.if ExitCode()!=STILL_ACTIVE ; process finished?
and ready2load, 0 ; clear the flag and
call LvGetFiles ; load the processed files
.endif
.endifBasically, you can thus:
- launch an external preprocessor
- watch its output in an edit window
- and proceed once the external process is no longer STILL_ACTIVE.
It is now also possible to have a permanent pipe, e.g. with cmd.exe, and to retrieve output from other processes with Launch$() in parallel.
Hi jj,
This code compiles fine and works as expected (with the latest MasmBasic)
include \masm32\MasmBasic\MasmBasic.inc
.data?
aNumber dd ?
Init
MovVal aNumber,Input$("Input: ")
add aNumber, 123
Print "Result: ",Str$(aNumber)
Exit
end start
But if you shorten the input message like this:
include \masm32\MasmBasic\MasmBasic.inc
.data?
aNumber dd ?
Init
MovVal aNumber,Input$("N: ")
add aNumber, 123
Print "Result: ",Str$(aNumber)
Exit
end start
Then the result is compilation error
Quote
JWasm v2.10pre, Dec 30 2012, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
input.asm(7) : Error A2172: Initializer magnitude too large:
repargA(55)[MasmBasic.inc]: Macro called from
cStyle$(99)[MasmBasic.inc]: Macro called from
Input$(3)[MasmBasic.inc]: Macro called from
input.asm(7): Main line code
input.asm: 11 lines, 1 passes, 78 ms, 0 warnings, 1 errors
Is this a bug?
Quote from: anta40 on January 08, 2013, 02:10:34 PM
Is this a bug?
YES, fat and ugly (but harmless). Will be fixed asap, thanks for the feedback :t
The reason is that "abcd" is an immediate for the macro engine, not a string. For example, you can write
mov eax, "abcd" or
mov al, "x". But the macro can check for the <"> and then decide to treat it as a string. The bug didn't show up until now because all my test examples had more then four chars - and then JWasm & Ml are clever enough to realise "no, can't fit into 32 bits, so it must be a string". Cute, ain't it? ;)
Ah I see.
Indeed it's not harmful, just a little annoying.
I was confused for a while why my code wouldn't compile, until somehow I reverted back the input message, and finally the assembler accepted it.
:P
Until the new version is ready, you can use Chr$() as a workaround:
; MovVal aNumber,Input$("nu: ", "1000")
MovVal aNumber, Input$(Chr$("nu: "), "1000")
I have this problem :(
Then the result is compilation error
MasmBasic.inc (5871): error A2102: Symbol not defined: CP_UTF8
MasmBasic.inc (6288): error A2102: Symbol not defined: OFN_ENABLESIZING
MasmBasic.inc (6289): error A2102: Symbol not defined: OFN_ENABLESIZING
some solution?
both symbols are defined in windows.inc
you are simply not including the proper include files
it is possible that you are trying to assemble a file on a different drive than the one where masm32 is installed
Dave is correct, they are defined in Windows.inc
How does your source start? There should be no problem if your first line is
include \masm32\MasmBasic\MasmBasic.inc
On top of MasmBasic.inc you find this:
IFNDEF _wininc_
include \masm32\include\masm32rt.inc
.686 ; JWasm needs this
.xmm
ENDIF
In other words, all standard includes are in anyway.
With 145 downloads, the Jan 2 version got a bit stale, so I guess it's time for an update.
Many improvements "under the hood", but also some visible goodies; inter alia, all arrays (strings, byte/word/dword, REAL4/8/10, structures) can now be dynamically defined, e.g.
Dim My$()
Dim NormalDist() As DWORD
Dim Sinus() As REAL8
Note though, that values can be assigned only incrementally, e.g.
Dim My$()
Let My$(99)="Hello" ; illegal, will throw an error
xor ecx, ecx
.Repeat
Let My$(ecx)=Str$("#%i", ecx)
inc ecx
.Until ecx>9999
The deb macro has learned to display flags (without changing them, of course):
deb 4, "End of loop:", ecx, flags, FLAGS
flags displays carry, zero, sign and overflow, FLAGS the whole set:
End of loop:
ecx 10000
flags: czso
FLAGS: cpAzstIdo
c means carry clear, C carry set, etc.
Last but not least, attached a minimally modified \Masm32\examples\exampl01\generic\generic.asm:
1. Includes were replaced by the usual one-liner: include \masm32\MasmBasic\MasmBasic.inc
2. These few lines were added below "end menu commands":
;====== end menu commands ======
.elseif uMsg == WM_CREATE
ToolTips start ; we'd like to see the country names
ToolTips end
Dim NormalDist() As DWORD ; read the data of a normal distribution from file
ArrayRead NormalDist(), "NormalDist.dat"
ArrayLoadMap 0, "Europe" ; load a map
Dim Sinus() As REAL8 ; define an array for a sinus curve
xor ecx, ecx
push 180
fild stack ; stack is an equate for dword ptr [esp]
push ecx
fldpi
fdivr
fstp REAL4 PTR stack[4]
.Repeat
mov stack, ecx
fild stack
fmul REAL4 PTR stack[4]
fsin
fstp Sinus(ecx)
inc ecx
.Until ecx>500
pop ecx
pop eax
.elseif uMsg == WM_MOUSEMOVE
ArrayMapRegion(lParam, 0, hWnd)
.elseif uMsg == WM_PAINT
ArrayPlot hWnd, RgbCol(200, 255, 240) ; init with window (or control) handle and background colour
ArrayPlot 0, RgbCol(200, 200, 200), lines:2 ; plot map 0 as loaded above, with grey border and 2px lines
ArrayPlot Sinus() ; plot the sinus curve defined above
ArrayPlot NormalDist()
; ------ here you could add additional features, e.g. a legend ------
ArrayPlot exit, "Europe" ; finish with a title
.elseif uMsg == WM_CLOSE
The output? Check yourself :biggrin:
P.S.: With more recent MasmBasic versions, replace the start: label with Init, otherwise it will crash.
so - what are we looking at, Jochen ???
is it, in any way, related to the pr0n ban in Iceland ? :redface:
it seems not to have affected pr0n in Western Europe :P
btw - when i "install" MasmBasic, where are the read-me's that outline how to do that ?
Quote from: dedndave on March 02, 2013, 10:41:08 AM
btw - when i "install" MasmBasic, where are the read-me's that outline how to do that ?
After unzipping with "use folder names" with the root of your Masm32 as start directory, there is one in
\Masm32\RichMasm\ReadMeMasmBasic.txt
\Masm32\MasmBasic\MbGuide.rtf is more interesting, though ;-)
Quote from: jj2007 on March 02, 2013, 10:45:17 AM\Masm32\MasmBasic\MbGuide.rtf is more interesting, though ;-)
yea, if one has no problem with developing eye cancer ;-D
BTW: what about double buffering?
Quote from: qWord on March 02, 2013, 11:00:57 AM
BTW: what about double buffering?
What do you mean??
Quote from: jj2007 on March 02, 2013, 11:14:45 AM
Quote from: qWord on March 02, 2013, 11:00:57 AM
BTW: what about double buffering?
What do you mean??
Sry, I was talking about the example with ArrayPlot - it flickers on resizing.
Yes, that's true. I wanted to keep the example simple. To reduce the flicker, do the following:
- line 135:
mov wc.style, CS_BYTEALIGNWINDOW
- in line 238, add:
.elseif uMsg == WM_SIZE
invoke InvalidateRect, hWnd, 0, 0
.elseif uMsg == WM_CREATE
It's much simpler: set the background brush to zero
mov wc.hbrBackground, 0
:biggrin:
Good trick, but you still need the InvalidateRect in the WM_SIZE handler. Even better but CPU-hungry: InvalidateRect in the WM_SIZING handler.
Quote from: jj2007 on March 02, 2013, 11:33:01 AM
Good trick, but you still need the InvalidateRect in the WM_SIZE handler. Even better but CPU-hungry: InvalidateRect in the WM_SIZING handler.
your original example does not need that, because the window class has the CS_HREDRAW and CS_VREDRAW style.
i didn't think CS_BYTEALIGNWINDOW meant much on modern displays
Quote from: qWord on March 02, 2013, 11:37:44 AM
your original example does not need InvalidateRect, because the window class has the CS_HREDRAW and CS_VREDRAW style.
That's right - CS_HREDRAW or CS_VREDRAW plus a zero background brush seems to give the best results. Thanks, the new version is uploaded above :t
The documentation is still incomplete; for example, you can add a margin and a legend:
.elseif uMsg == WM_PAINT
ArrayPlot hWnd, RgbCol(200, 255, 240) ; init with window (or control) handle and background colour
ArrayPlot 0, RgbCol(200, 200, 200), lines:2, 00001900h ; plot map 0 as loaded above, with grey border and 2px lines, margin right=19h
ArrayPlot Sinus() ; plot the sinus curve defined above
ArrayPlot NormalDist()
; ------ here you could add additional features, e.g. a legend ------
invoke SetBkMode, APs.apMemDC, TRANSPARENT
invoke SelectObject, APs.apMemDC, LegendFont
invoke TextOut, APs.apMemDC, 380, 100, Chr$("Legend"), 6
ArrayPlot exit, "Europe" ; finish with a title
Hi Jochen,
Quote from: jj2007 on March 02, 2013, 11:48:14 AM
Thanks, the new version is uploaded above :t
in which post? I'd like to test it.
Gunther
Hi Gunther,
It's always attached to the first post in this thread. Feedback welcome ;)
Thank you, Jochen. :t
Gunther
Version 6 March uploaded here (http://www.masm32.com/board/index.php?topic=94.0). It fixes a nasty little bug in the ArrayRead macro (the wrong file was closed). Usage:
Dim rc4() As REAL4 ; can be REAL4, REAL8, DWORD, ... structures
ArrayRead rc4(), "MyReal4.dat"
To compensate for this bug :redface:, I added ArrayMean:
ArrayMean MyR8() ; all array elements are added up, then the sum is divided by the count
Print Str$("Resall=\t%f\n", ST(0)) ; the resulting mean is left on the FPU
fstp st
ArrayMean MyR8(XY) ; same as before but we assume the array consists of x,y pairs
Print Str$("ResY=\t%f\n", ST(0)) ; the mean of the Y elements is returned in ST(0)
fstp st
Print Str$("ResX=\t%f\n", ST(0)) ; the mean of the X elements is returned in ST(1)
fstp st
Rem returns mean(s) on the FPU and total number of elements in eax
Version 24 March uploaded (download: top of thread (http://www.masm32.com/board/index.php?topic=94.0))
New functions are ArraySet, SetPoly3 and GetPoly3, see example below and \Masm32\MasmBasic\MbGuide.rtf
As shown in the repeat loop below, AllPts(ecx+1) is now valid syntax (same for string arrays)
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim My3Pts(5) As DWORD ; create an array with 3 XY pairs, i.e. 6 elements (0 .. 5)
ArraySet My3Pts() = 1, 100, 2, 300, 4, 150 ; assign XY values (ArraySet can be handy but any other array works, too)
SetPoly3 My3Pts() ; create coefficients for a 3-point polynomial, i.e. Y=a0+a1*X+a2*X2
Dim AllPts(11) As REAL4 ; create a destination array with 12 elements
Print "N", Tb$, "X", Tb$, "Y", Tb$, "Y(ecx)" ; the last column uses the "direct" variant GetPoly3(X)
GetPoly3(AllPts()) ; fill starting from X=0, create coefficients for Y=a0+a1*X+a2*X2
add eax, eax
push eax
xor ecx, ecx
.Repeat ; print N, X, Y=f(x), Y=f(2*X)
Print Str$("\n%i\t", ecx/2), Str$("%2f\t", AllPts(ecx)), Str$("%3f\t", AllPts(ecx+1)), Str$("%3f", GetPoly3(ecx))
fstp st ; pop the return value from the FPU
add ecx, 2
.Until ecx>=stack
pop eax
Inkey CrLf$, "ok"
Exit
end start
Output:
N X Y Y(ecx)
0 0.0 -283.0 -283.0
1 1.0 100.0 300.0
2 2.0 300.0 150.0
3 3.0 317.0 -733.0
4 4.0 150.0 -2.35e+03
5 5.0 -200.0 -4.70e+03
Latest addition to MasmBasic is an interface to Excel - more in the Easter Egg (http://masm32.com/board/index.php?topic=1733.0) thread.
Note that when you use the File, New Masm source menu in RichMasm, the interface is offered here:
Client & server example for InterProcessCommunication (IPC)
Masm2Excel an easy-to-use DDE interface to MS Excel
MasmBasic console app more examples using BASIC syntax
However, the MB archive is at the 512kB limit, therefore I couldn't squeeze it in. Extract Masm2Excel.asc from post #1 of the Easter Egg (http://masm32.com/board/index.php?topic=1733.0) thread to \Masm32\RichMasm\Res\Masm2Excel.asc to add this sample to the templates.
With version 5 April, the xlsHotlink macro works now just fine :biggrin:
A little warning: All macros that write to Excel, whether VBA or XLA or MasmBasic, do not preserve the previous state, i.e. there is no undo. If you really need undo, use xlsRead$("yourselection") and handle it manually.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
xlsConnect ; no args=Excel, System
.if !Zero? ; non-zero means success
xlsOpen "\Masm32\RichMasm\Res\LifeExOecd.xls" ; we open a sample spreadsheet
.if !Zero? ; non-zero signals success
; xlsCommand "[app.activate()]" ; optional: activate Excel
xlsConnect "LE Males at birth" ; tell Excel to which sheet you want to talk
.if !Zero? ; non-zero signals success
.if rv(GetConsoleWindow) ; you may print to the console...
ConsoleColor cBlack, cYellow ; make the spaces visible that Excel exports
Print "Current selection=[", xlsRead$(), "]", CrLf$ ; no args means current selection
.else
ifdef hEdit ; this section would be typical for a GUI application
SetWin$ hEdit='R1C1:R9C5=['+xlsRead$("R1C1:R9C5")+']'+CrLf$ ; ... or set window content
AddWin$ hEdit="Extract #2=["+xlsRead$('R9C1:R12C5')+"]"+CrLf$ ; and add bits & pieces
xlsHotlink "R5C1:R38C2", hEdit ; see how user modifies a selected area
endif
.endif
; writing is possible but attention, there is no undo (as for all modifications done by Excel macros)
xlsWrite "R1C1", Cat$("This sheet was modified on "+Date$+", "+Time$)
.endif
xlsClose 0 ; close the file without saving (0=don't save, 1=save, no arg: ask)
.endif
xlsDisconnect ; say bye to Excel
.endif
Inkey "ok"
Exit
end start
Jochen,
looks like a rock solid work. :t
Gunther
Danke, Gunther :icon14:
Although DDE is an old technology, there are some arguments for using it - it's fast, lightweight, and there is no "version hell" as (reportedly) with the alternative COM technology. What I really needed was pulling tables programmatically out of an Excel file - sounds simple but if you don't want the user to install add-ins (with all the nice warnings about untrusted software etc), then DDE is probably the only option.
One problem is the documentation; DDE uses the old Excel 4.0 macro language, the only official source is "MacroFun.hlp" from Microsoft Support (http://support.microsoft.com/kb/128185).
Quote
What I really needed was pulling tables programmatically out of an Excel file
If it is just for that,ODBC is better (same language since ....)
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
If it is just for that,ODBC is better (same language since ....)
What is better with ODBC?
- DDE = dinosaur technology
- COM/OLE = pleistocene
- ODBC = ??? ( perhaps eocene? )
Quote
What is better with ODBC?
The Use of sql with it , simplify the work.
Simple to use,you don't need to know all the langage.
Access can generate SQL for you.
http://msdn.microsoft.com/en-us/library/bb545450.aspx (http://msdn.microsoft.com/en-us/library/bb545450.aspx)
2012 isn't so old.
i mentioned in the other thread that i had to have Excel for a business client
what i did at the time was - Save Special (without the cell formulas) - Save As CSV
then, i wrote a csv2bin program in 16-bit code :P
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
Quote
What I really needed was pulling tables programmatically out of an Excel file
If it is just for that,ODBC is better (same language since ....)
Hi Yves,
Please show me. Write a little example - just extracting a table by RnCn:RmCm coordinates.
The testfile is at \Masm32\RichMasm\Res\LifeExOECD.xls
:t
The file is not a database.
A database had columns titles on the first line.
Do it and no more problems.
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
If it is just for that,ODBC is better (same language since ....)
There is an old German proverb: Wer gackert muss auch legen. Free translation "He who cackles must lay an egg".
Waiting for your sample code showing that "ODBC is better", Yves :biggrin:
(the requirement is very simple, "get data out of Excel without the user having to install an add-in or a macro; establish a hotlink so that Excel sends data to your proggie every time the Excel user has changed a cell". It would also nice to preserve the formatting as shown in the attached example - source in \Masm32\RichMasm\Res\XlsViewer.asc. If you change the ending to .edm, you can even view it in EditMasm, as it's RTF...)
Quote
What I really needed was pulling tables programmatically out of an Excel file
For That,not for all thing you want to do.
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
Waiting for your sample code showing that "ODBC is better", Yves
Quote from: jj2007 on April 05, 2013, 05:53:12 AM
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
Waiting for your sample code showing that "ODBC is better", Yves
I cannot see why he needs to provide "sample code" - that's an additional requirement imposed by you, troll! :icon_mrgreen:
Actually, it is sufficient if a plausible reason is supplied that makes obvious - more or less - that ODBC is at least in one aspect better than DDE.
One possible reason that comes into my mind is that DDE requires a window for communication, while ODBC does NOT requires this.
Quote from: japheth on April 05, 2013, 06:48:44 AMOne possible reason that comes into my mind is that DDE requires a window for communication, while ODBC does NOT requires this.
Thanks for this clarification, Andreas. I wonder, though, why the attached executable works - must be an invisible window then ::)
Source is in \Masm32\RichMasm\Res\Masm2Excel.asc, the Excel sheet at \Masm32\RichMasm\Res\LifeExOECD.xls ;-)
Still waiting for demo code (or at least: arguments) why ODBC is better than DDE for grabbing data from an Excel sheet ;-)
EDIT: To complete the DDE interface, I added four new macros, ddeConnect, ddeDisconnect, ddeCommand and ddeRequest$(). This snippet shows the Firefox URL currently loaded, and if the user presses
y, it opens a new page (code for MSIE attached):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
ddeConnect "Firefox|WWW_GetWindowInfo"
.if !Zero?
PrintLine "Current URL= ", ddeRequest$("URL")
ddeDisconnect
Inkey "Open a new page (y)?"
.if eax=="y"
ddeConnect "Firefox|WWW_OpenURL"
.if !Zero?
ddeCommand "http://masm32.com/board/index.php?action=unread"
ddeDisconnect
.endif
.endif
.endif
Inkey CrLf$, "bye"
Exit
end start
Bugfix concerning \Masm32\RichMasm\Res\Masm2Excel.asc, line 51:
Wrong:
mov ecx, Instr_(esi, "[Book") ; this might fail for a non-English Excel version
.if ecx
.if Instr_(ecx, esi, Tb$)
xlsConnect Mid$(esi, ecx, edx-1) ; connect to the new sheet
Let TopBot$=String$(9, Cat$("xxxxxxxxx"+Tb$))+"x"
xlsWrite "R2C3:R2C14", TopBot$
Right:
mov ecx, Instr_(esi, "[Book") ; this might fail for a non-English Excel version
.if ecx
.if Instr_(ecx, esi, Tb$)
xlsConnect Mid$(esi, ecx, edx-ecx) ; connect to the new sheet
Let TopBot$=String$(9, Cat$("xxxxxxxxx"+Tb$))+"x"
xlsWrite "R2C3:R2C14", TopBot$
Excel 2003 did not complain about being connected to [Book1]Sheet1 whatever, but Excel 2010 didn't like it :biggrin:
Updated library here (http://masm32.com/board/index.php?topic=94.0), as always.
Quote from: jj2007 on April 05, 2013, 07:31:39 AM
Thanks for this clarification, Andreas. I wonder, though, why the attached executable works - must be an invisible window then ::)
Yes, I guess that's true. Sorry, can't really run your sample because I threw away the MSO BS from this machine - and the one where it's still installed is now too noisy for my taste.
The DDE demo in \Masm32\RichMasm\Res\Masm2Excel.asc works fine with DDE and Excel 2010 Starter Edition on Italian Win7-64. Note that the "starter" editions do not run any macros... but DDE works just fine. Probably some big corporations running legacy software had a chat with the M$ marketing department. Won't go into detail here because it would violate the forum rules ;-)
xlsCommand "[new(1)]" ; let Excel create a new workbook (works fine on non-English Excel versions!)
Let esi=xlsSysRead$("Topics") ; we must find the sheet
mov ecx, Instr_(esi, "[Book") ; this might fail for a non-English Excel version
.if !ecx
mov ecx, Instr_(esi, "[Cartel") ; let's try Italian - OK on Win7-64, Excel Starter 2010 (does not support macros!!)
.endif
.if ecx
.if Instr_(ecx, esi, Tb$)
xlsConnect Mid$(esi, ecx, edx-ecx) ; connect to the new sheet
Update 15 April (download from post #1 (http://masm32.com/board/index.php?topic=94.msg264#msg264)):
- fixed a bug in Replace$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1079)
- Clip$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1099) had a 160k limit, now the limit is available memory
- Exp10, Exp2, ExpE and ExpXY (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1192) implemented (special thanks to qWord :t (http://masm32.com/board/index.php?topic=1783.msg18292#msg18292))
Update 18 April (download from post #1 (http://masm32.com/board/index.php?topic=94.msg264#msg264)):
- fixed a bug in StringToArray (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1130) (the string to numerical array variant pushed one dword too much; the string to string array variant was OK)
- Pelles C "Hello World" example added (see New Masm source in the RichMasm editor)
- SetPoly3 (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1124) MyArray(ecx) is now possible, i.e. take 3 xy pairs starting with element ecx (where ecx = 0, 2, 4...)
- Str$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186)() accepts now single quotes (rarely needed, but I had a problem with DDE...):
mov row, 3
xlsCommand (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1085) Str$('[select("R%iC5")]', row) ; select("R3C5")
Finally, the handling of resource strings was improved, so that you can use two of them in MsgBoxes, as shown below for Unicode (same for the Ansi version):
include \masm32\MasmBasic\MasmBasic.inc
Init
wMsgBox 0, wRes$(2), wRes$(3), MB_OK
Exit
end start
Rsrc
STRINGTABLE ; RichMasm creates the rc file "on the fly"; edit the strings, then press F6 to assemble, link & run
BEGIN
2, "Нажмите на эту кнопку" ; "Click on this button" in Russian
3, "Добро пожаловать" ; "Welcome" in Russian
END
Rsrc
You're a hard working man, Jochen. :t Thank you for the update.
Gunther
Thanks, Gunther ;-)
In the meantime, I had to fix a little bug: CL$() and wCL$() choked after arg #126. Now the number of arguments from the commandline is apparently limited by Windows; for example, under Win7-32 you can pass up to 32767 bytes via CreateProcess aka Launch (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1045)(). Little test app attached.
I seized the occasion to add one more macro:
PickFont addr hFont ; use the font dialog to change the font whose handle is in hFont
PickFont addr hFont, hEdit ; apply to edit control (if user didn't cancel)
Quote from: jj2007 on May 06, 2013, 08:43:25 PM
In the meantime, I had to fix a little bug: CL$()...
And I introduced a fresh one on that occasion: CL$() with no args (i.e. "return the complete commandline") crashed. Concerns only version 6 May and is now fixed with version 8 May attached on top of this thread. Apologies :redface:
It is possible to share data between two applications using the same DLL. In Win-16, that was the default, in Win-32 you need to declare a shared data segment (more at MSDN (http://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.80).aspx)).
Strangely enough, it is even possible to have a joint memory area between two instances of an application:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
MyShared SEGMENT read write shared "BSS"
TheCount dd ?
MyShared ends
Init
inc TheCount
.if TheCount<=2
Delay 500 ; if you see "1" on screen more than once, press Ctrl C
Launch CL$(0) ; launch another instance
.endif
Inkey Str$("n=%i\n", TheCount)
Exit
end start
Output:
1
2
3
(hit any key three times to exit - there are three inkey statements)
Sharing segments as shown above works for JWasm and Masm 8.0 and higher. For Masm 6.15, there is a workaround as shown below, but it needs the linker option...
/SECTION:.bss,rws
... which fails miserably with POLINK (warning: /SECTION:.bss ignored; section is missing)
.data?
TheCount dd ?
Credits go to Japheth (http://forum.pellesc.de/index.php?topic=5476.msg20945#msg20945) and qWord (http://www.masmforum.com/board/index.php?topic=14096.msg111856#msg111856)
JJ,
I have seen IPC done this way but its rather clunky along side a memory mapped file and conventional messaging. The memory mapped file provides the shared memory area of more or less any size you like while the messaging using the HWND_BROADCAST identifier can be used to signal when data is available to any other app that can access the shared memory.
Hutch,
I wouldn't call it clunky, it's really as simple as declaring myvar dd 123 in the .data section. Memory-mapped files are great for many purposes, sure.
But I have to admit that I don't see many uses for shared segments. As a proof of concept, I attach a little app that launches itself three times, declaring instance 0 as "server" and 1+2 as "clients". The common segment has an array where each instance stores its window handle, so no need for broadcasting:
MyShared SEGMENT read write shared "BSS"
MyCount dd ?
hWinByInstance dd 20 dup(?)
MyShared ends
The server can send a WM_COPYDATA message, the clients can handle them. Instead of that message, shared memory could be used to copy strings from server to client. IIRC, WM_COPYDATA eats around 4,000 cycles, which is quite a lot. Mem to mem should be faster...
On startup, MyCount is increased. Each instance knows its identity, and uses it e.g. to decide the x position on the screen, and whether to add pushbuttons or not.
Hi Jochen :t
Yes, I can confirm that this way of IPC in suitable cases is the best possible, just unbeatable: it's simple, reliable and fastest.
As one more proof of the concept: RAM Clear working in Advanced Mode - when it is unlimited with the size of memory it may free - working in that way. It launch "subsystems" - "clients" in your terminology here - and all interaction between server-controller-interface-father and client-subsystem-child is going via shared section of the same EXE.
RAM Clear has multiprocess, multithreaded concept, and in the extents it was designed for, special shared section does its job for IPC best of any other method.
But one needs to remember that with such an IPC way the designed controlling system should be properly designed for preemptiveness and reenterantness - i.e., multithreading (here this is equal to multiprocessing) there is no serialization like in message pump of the target-window process, like if "messages-way" IPC is using. I.e., all working programs can change data in the shared section just simultaneously, and there should be a mechanism to protect "atomical values" from changing simultaneously.
On the alpha-stage RAM Clear there were a fullscale tests with 96 working subsystems (96 child processes launched by a father process). So, this concept is really good one - when it is suitable :t
After over 150 downloads, it seems time for an update...
Apart from fixing minor glitches, there are three significant changes in MasmBasic of 26.7.2013:
1. MasmBasic's debug macro has learned to display variables and registers also in hex and binary format:
deb 1, "On loop entry:", al, ecx, $esi, xmm0, xmm1, ST, ST(5) ; xmm in lowercase, FPU regs in uppercase
deb 4, "#4 will show in the console:", xmm0, f:xmm0 ; display xmm0 as integer (default) and float with f: prefix
deb 5, "#5 will be written to DebLog.txt:", ebx, $My$, $MyArray$(n)
usedeb=0 ; disable debugging completely (no code inserted - very handy...)
deb 1, "This box will never pop up", eax
usedeb=16 ; force hex display
deb 4, "Hexadecimal:", eax, xmm1, ST(3) ; limited to 32 bits, i.e. low dword of xmm regs, FPU as int 32
usedeb=2 ; force binary display
deb 4, "Binary:", eax, xmm1, ST(3) ; limited to 32 bits
usedeb=1 ; decimal display (default)
deb 4, "Multiple:", eax, x:eax, b:eax ; override usedeb: show arguments in decimal, hexadecimal and binary format
If you are still not desperate enough to launch Olly, give deb a try.
Nothing is more powerful for bug-chasing.
2. ClearLocals replaces ClearLocalVariables and is now much simpler (and a lot faster, too (http://masm32.com/board/index.php?topic=2137.0)):
MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT
LOCAL v1, v2, rc:RECT, buffer[100]:BYTE
ClearLocals ; first line after the LOCALs
MsgBox 0, Str$("The value of v1: %i", v1), "Test clv:", MB_OK
ret
MyTest endp
ClearLocals is fast, compact (5 bytes per call), and leaves all registers intact.
3. StackBuffer has become simpler, and you can use more than one buffer:
MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT
LOCAL rc:RECT, sbuf1, sbuf2, whatever[100]:BYTE
; optional: ClearLocals ; first line after the LOCALs
mov sbuf1, StackBuffer(100000) ; allocate two fat buffers, and make sure
mov sbuf2, StackBuffer(4000h) ; they are 16-byte aligned for use with SSE2
PrintLine "Start buffer 1:", Tb$, Hex$(sbuf1)
PrintLine "Start buffer 2:", Tb$, Hex$(sbuf2)
StackBuffer() ; release second buffer
StackBuffer() ; release first buffer (sb without args = free the buffer)
ret
MyTest endp
- buffer size is limited by start address of stack;
- the start address is aligned to 16 bytes for use with SIMD instructions
- can be combined with ClearLocals, but no zero-init performed for the stack buffer
- StackBuffer does the stack probing for you
Download the library from the top of this thread. (http://masm32.com/board/index.php?topic=94.0)
A small addition for version 29 July concerns the crtbuf macro (see also StackBuffer() above):
crtbuf ThisExe$, MAX_PATH ; create a buffer in the uninitialised data section
invoke GetModuleFileName, 0, ThisExe$, MAX_PATH ; use it...
crtbuf pBuffer, 1000000, 16 ; create a 1 Mio bytes buffer in .data?, align 16 for use with SSE2
So SIMD fans can now specify 16-byte alignment (default is DWORD). Note that StackBuffer() is always aligned to 16 bytes but not zeroed.
Jochen,
Quote from: jj2007 on July 29, 2013, 07:16:26 PM
So SIMD fans can now specify 16-byte alignment (default is DWORD). Note that StackBuffer() is always aligned to 16 bytes but not zeroed.
good feature. It avoids a GPF in some cases. Thank you. :t
Gunther
MasmBasic version 5 August 2013 (http://masm32.com/board/index.php?topic=94.0) is much improved on the deb and Hex$() macros. Example:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
; create a WORD array (byte, dword, qword, realX are also valid sizes):
Dim MyW() As WORD
mov MyW(0), 100 ; give it a start value
xor ecx, ecx
.Repeat
mov ax, MyW(ecx)
add ax, cx
mov MyW(ecx+1), ax
deb 6, "Fill a WORD array", ecx, MyW(ecx), MyW(ecx+1) ; print the first 6 iterations to the console
inc ecx
.Until ecx>999
Print Str$("\n%i loops OK\n", ecx)
Print Str$("MyW(ecx-2)=%i\n", MyW(ecx-2)) ; show the last two values assigned
Inkey Str$("MyW(ecx-1)=%i\n", MyW(ecx-1))
Exit
end start
Output:
Fill a WORD array
ecx 0
MyW(ecx) 100
MyW(ecx+1) 100
Fill a WORD array
ecx 1
MyW(ecx) 100
MyW(ecx+1) 101
Fill a WORD array
ecx 2
MyW(ecx) 101
MyW(ecx+1) 103
Fill a WORD array
ecx 3
MyW(ecx) 103
MyW(ecx+1) 106
Fill a WORD array
ecx 4
MyW(ecx) 106
MyW(ecx+1) 110
Fill a WORD array
ecx 5
MyW(ecx) 110
MyW(ecx+1) 115
1000 loops OK
MyW(ecx-2)=38851
MyW(ecx-1)=39849
The Hex$() macro can now handle more sizes, including the 4 DWORDS of xmm registers, and has learned to display exotic formats, such as FPU and XMM registers:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
.data
MyByte db 12h
MyWord dw 1234h
MyDword dd 12345678h
MyQword dq 1234567812345678h
MyReal8 REAL8 1234567812345678r ; r means the hex representation of a real number
MyPackedQwords dq 11aa22bb33cc44ddh, 55aa66bb77cc88ddh
Init
mov ecx, 12345678h
PrintLine Hex$(cl) ; reg8, 12 - same for dh, ah etc
PrintLine Hex$(ch) ; reg8, 12 - same for dh, ah etc
PrintLine Hex$(cx) ; reg16, 1234
PrintLine Hex$(ecx) ; reg32, 12345678
PrintLine Hex$(123) ; immediate
PrintLine Hex$(MyByte) ; global and local variables
PrintLine Hex$(MyWord)
PrintLine Hex$(MyDword)
PrintLine Hex$(MyQword) ; QWORD will be displayed with one space as 12345678 90123456
movups xmm1, oword ptr MyPackedQwords
PrintLine Hex$(xmm1) ; if QWORD is not enough, get e.g. 11AA22BB 33CC44DD 55AA66BB 77CC88DD
PrintLine Hex$(MyReal8) ; same as QWORD
fldpi
PrintLine CrLf$, "PI=", Hex$(ST) ; PI as 10-BYTE hex
Let esi=CrLf$+"Result = "+Hex$(287454020)+"h" ; in case you need the trailing h or a leading 0x, use Let or Cat$()
Inkey esi
Exit
end start
Output:
78
56
5678
12345678
0000007B
12
1234
12345678
12345678 12345678
11AA22BB 33CC44DD 55AA66BB 77CC88DD
12345678 12345678
PI=4000 C90FDAA2 2168C235
Result = 11223344h
If you find a problem, please let me know.
Version 5 August of MasmBasic displayed OWORDs in the incorrect order. The bug is fixed in version 12 August. (http://masm32.com/board/index.php?topic=94.0)
The reason, or rather: my bad excuse, is that I try to keep compatibility to good old MASM 6.15 - and the latter doesn't know about OWORDs. My workaround is usual to declare two QWORDs instead:
; MyO OWORD 00112233445566778899aabbccddeeffh ; no good for ML 6.15 and lower
; MyO QWORD 0011223344556677, 8899aabbccddeeffh ; solution #0 - WRONG
MyO QWORD 8899aabbccddeeffh, 0011223344556677 ; solution #1 - RIGHT
As you can easily guess, I had tested the new Hex$(xmm1) with solution #0 :redface:
Below a simple demo (the deb macro uses Hex$() internally):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
.data
O0 OWORD 0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh
O1 OWORD 0FFFF99FFFFFFFFFFFFFF11FFFFFFFFFFh
O3 OWORD 0ffeeddccbbaa99887766554433221100h
Init
movups xmm0, O0
movups xmm1, O1
movups xmm3, O3
movaps xmm2, xmm0 ; copy for pcmpeqb
PCMPEQB xmm2, xmm1
deb 4, "x0/1/2", x:xmm0, x:xmm1, x:xmm2, x:xmm3
Print CrLf$, "16 bits", Tb$, Tb$, Tb$, "5432109876543210", CrLf$
PMOVMSKB eax, xmm2 ; show in ax where xmm0 differs to xmm1
xor ecx, ecx
not ax ; we are interested in bits set
deb 4, "MSKB", b:ax
bsr ecx, eax
deb 4, "msb set", ecx
bsf ecx, eax
deb 4, "lsb set", ecx
Inkey
Exit
end start
Output:
x0/1/2
x:xmm0 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
x:xmm1 FFFF99FF FFFFFFFF FFFF11FF FFFFFFFF
x:xmm2 FFFF00FF FFFFFFFF FFFF00FF FFFFFFFF
x:xmm3 FFEEDDCC BBAA9988 77665544 33221100
16 bits 5432109876543210
MSKB b:ax 0010000000100000
msb set ecx 13
lsb set ecx 5
Quote from: jj2007 on May 23, 2012, 10:16:07 PM
MasmBasic is a library that allows to use BASIC syntax in assembler, i.e. it is not a "separate" language but rather a library of macros and routines, fully compatible with the latest Masm32 SDK (version 11) (http://masm32.com/), MASM (http://www.microsoft.com/downloads/en/details.aspx?familyid=7a1c9da0-0510-44a2-b042-7ef370530c64&displaylang=en) (from version 6.15 upwards, see e.g. version 8.0 (http://www.masm32.com/board/index.php?topic=13529.msg105895#msg105895)) and JWasm (http://www.japheth.de/JWasm.html#jwdownload). The usual disclaimers apply - do not use for military purposes, in hospitals and anywhere else where buggy applications could cause damage. You have been warned 8)
I wish you had posted that earlier.
I used it to write a program that monitors C-eye-PAV.
I think you are safe though.
Andy
Update 15 August (download (http://masm32.com/board/index.php?topic=94.0)):
Qcmp, Ocmp
.data ; for testing
qSmall qWORD 7700000000000001h
qBig qWORD 7700000000000003h
oSmall OWORD 77000000000000000000000000000001h
oBig OWORD 77000000000000000000000000000003h ; OWORD for JWasm and higher ML.exe versions
; oBig qWORD 00000000000000003h, 7700000000000000h ; 2 QWORDS for ML 6.15
.code
Qcmp qBig, qSmall ; compare two global variables
mov ecx, offset oBig ; use a pointer ...
Ocmp ecx, oSmall ; ... for one (or both) of them
movups xmm0, OWORD PTR oSmall ; even ML 6.15 understands that
oqDeb=1 ; if this flag is set, Qcmp or Ocmp print e.g. "ecx greater xmm0" to console
Ocmp ecx, xmm0 ; a pointer and an XMM reg (xmm0...xmm2 will be trashed)
deb 4, "Result", flags ; CzSo, i.e. Carry? and Sign? set
Rem
- returns flags as in a cmp eax, edx comparison (control for overflow!)
- trashes eax and edx, xmm0 and xmm1; do not use edx as input
- you cannot use both ecx and ebx as input pointers (an error will be thrown)
## for comparing floats (REAL4, REAL8, REAL10): ##
Fcmp
MyPI_hi REAL4 3.14160
...
Fcmp MyPI_hi, PI, medium ; PI is what you think it is
.if FcmpLesser
Print Str$("MyPI_hi at %f is lower than the real PI\n", MyPI_hi)
.elseif Zero?
Print Str$("MyPI_hi at %f is exact\n", MyPI_hi)
.else
Print Str$("MyPI_hi at %f is higher than the real PI\n", MyPI_hi)
.endif
Rem - returns Zero? and Sign? flags (and only these are valid): Sign? means "first arg below second arg"
- you may use FcmpGreater and FcmpLess (aka !Sign? and Sign?)
- single arg, e.g. Fcmp xmm1, tests for zero
- see also QCmp and Ocmp for comparing QWORDs and OWORDs
- almost any number formats can be compared, including xmm registers etc
Quote from: jj2007 on May 23, 2012, 10:16:07 PM
MasmBasic is a library that allows to use BASIC syntax in assembler, i.e. it is not a "separate" language but rather a library of macros and routines, fully compatible with the latest Masm32 SDK (version 11) (http://masm32.com/), MASM (http://www.microsoft.com/downloads/en/details.aspx?familyid=7a1c9da0-0510-44a2-b042-7ef370530c64&displaylang=en) (from version 6.15 upwards, see e.g. version 8.0 (http://www.masm32.com/board/index.php?topic=13529.msg105895#msg105895)) and
When I clicked on version 8, it said off limits.
Andy
Thanks, Andy - I just corrected the link to Erol's post. Caution, though, when going to the M$ site:
QuoteThe Microsoft Macro Assembler 8.0 (MASM) is a tool that consumes x86 assembly language programs and generates corresponding binaries.
Make a backup of your sources ;)
Or, much better idea, use JWasm (http://www.japheth.de/JWasm.html) - fully compatible with Masm32 and MasmBasic, and at least twice as fast as the latest M$ snails. RichMasm has now autodetection for JWasm:
; if OPT_Assembler not explicitly set, check if ML is old and JWasm is available
.if Exist("\Masm32\Bin\ml.exe")
.if Instr_(GfDate$(-1), "1999")
mov ecx, Chr$("\Masm32\bin\JWasm.exe")
.if Exist(ecx)
invoke lstrcat, edi, offset txOptAss
.else
MsgBox 0, Cat$("You need"+CrLf$+ecx), "Hi", MB_OK
.endif
.endif
.endif
PacMasm ? :biggrin:
(http://wallofgame.info/images/pacman3.png)
Quote from: dedndave on August 15, 2013, 05:01:13 PM
PacMasm ? :biggrin:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
GetFiles \Masm32\*.asm
push eax
For_ ebx=0 To eax-1
Kill Files$(ebx)
Next
Inkey Str$("Dave, wifey is waiting, and %i files are gone!!!!", stack)
Exit
end start :greensml:
:greensml:
C:\MASM32\>ML the_proper_code.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: the_proper_code.asm
Yum-yum!
C:\MASM32\>ML the_untidy_code.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: the_untidy_code.asm
the_untidy_code.asm(9) : warning A4011: multiple .MODEL directives found : .MODEL ignored
*sound of belch*
Post the sources, Alex :biggrin:
Jochen,
Quote from: jj2007 on August 15, 2013, 06:17:32 PM
Post the sources, Alex :biggrin:
he will, he will. Please be patient. :lol:
Gunther
Update 18 August concerns only MasmBasic's default editor, RichMasm (located in \Masm32\RichMasm\RichMasm.exe after installation):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
; if RichMasm finds at least one int 3 that is not commented out, the editor
; will launch \Masm32\OllyDbg\ollydbg.exe for the current exe with arguments
int 3 ; Hit F9 in Olly, it will stop here
Print "The commandline args are [", CL$(1), "] and [", CL$(2), "]"
Exit
end start
RichMasm options for seeing symbols in Olly:
OPT_Assembler JWasm ; download (http://www.japheth.de/JWasm.html) - must be present in \bin (ML 6.15 works, too)
OPT_DebugA /Zi ; activate symbols
OPT_Linker link ; Masm32 standard, i.e. version 6.14, must be present in \bin
OPT_DebugL /debug ; for debugging
OPT_Arg1 "Hello coder"
OPT_Arg2 "what's cooking in the Masm32 forum?"
Note that Olly must be present as \Masm32\OllyDbg\ollydbg.exe
When Olly starts a console app, the console window will be in the foreground. This is rarely what you want, therefore RichMasm has now learned to move Olly to the foreground, so that you can directly hit F9 without having to click the bl**dy console away.
Since the zipped package was very close to the Forum's 512k limit, I wrote an installer which pushed it down to 322k. Feedback sought regarding
- the EULA
- the extraction process
- whatever observation you may have 8)
Just open the attachment and double-click on MbSetup.exe
(It's not MSI, sorry, but it seems to do the job, too - source will be available soon)
P.S.: Second version posted, the first one didn't find the image for the title bar :(
P.S.: Third version attached, #2 tried to sell VB to Dave, and I hope that is fixed for the time being ;-)
P.S.: See reply #100 for version #4
oops - lol
it says MasmBasic is not for me, then googles VB for me :lol:
nothing cryptic about that message
i have some of my masm32 subfolders named a little differently
perhaps you could tell us which subfolders must be in place before throwing us to the wolves :biggrin:
great idea, though
i always wondered if i had it set up correctly, before
Quote from: dedndave on August 23, 2013, 01:08:23 PM
oops - lol
it says MasmBasic is not for me, then googles VB for me :lol:
Soooorry... that means I have to revise the routine that checks if user X is a valid member of the Masm32 community :redface:
What I did is check the registry for the asm_auto_file editor. If there is \Masm32\ in one of the possible entries, you are a good user. Which means you are a bad user, Dave :eusa_naughty:
call IsMasm32 ; check if user has Masm32 installed
.if eax
inc GoodUser
wLet Button1$="Accept && Install"
wLet Static$="MasmBasic will be installed to "+wChr$(M32$)+"MasmBasic"
.else
wLet Button1$="Continue" ; will open Google ;-)
wLet Static$="Bye..."
.endif
IsMasm32:
; If an entry exists in both HKLM\SOFTWARE\Classes and HKEY_CURRENT_USER\SOFTWARE\Classes,
; then the value of the entry in HKEY_CURRENT_USER\SOFTWARE\Classes takes precedence (MSDN (http://technet.microsoft.com/en-us/library/cc739822%28v=ws.10%29.aspx)).
; Win7: HKCU & HKCR
Let edi=GetRegVal("HKCU\SOFTWARE\Classes\asm_auto_file\shell\open\command", 0, "No luck in HKCU...")
.if !Instr_(edi, "\Masm32\", 1)
Let edi=GetRegVal("HKLM\SOFTWARE\Classes\asm_auto_file\shell\open\command", 0, "No luck in HKLM...")
.endif
.if !Instr_(edi, "\Masm32\", 1)
Let edi=GetRegVal("HKCR\asm_auto_file\shell\open\command", 0, "No luck in HKCR...")
.endif
.if !Instr_(edi, "\Masm32\", 1)
FileWrite "tmp.asm", "MasmBasic is great"
lea edi, TmpPath$
invoke FindExecutable, esi, Chr$("\"), edi
Kill esi
.endif
Clr$ esi
push Instr_(edi, "\Masm32\", 1)
.if eax
or ecx, -1
.Repeat
inc ecx
.Until byte ptr [edi+ecx]>="A"
sub edx, ecx
lea eax, [edi+ecx]
Let M32$=Left$(eax, edx+7)
.endif
pop eax
retn
end start
Quote from: jj2007 on August 23, 2013, 09:07:14 AM
Since the zipped package was very close to the Forum's 512k limit, I wrote an installer which pushed it down to 322k. Feedback sought regarding
- the EULA
- the extraction process
- whatever observation you may have 8)
Just open the attachment and double-click on MbSetup.exe
(It's not MSI, sorry, but it seems to do the job, too - source will be available soon)
P.S.: Second version posted, the first one didn't find the image for the title bar :(
Just downloaded it,
Jochen :t
As for MSI - no need in excuses - don't like MSI packages :biggrin:
As for search for "asm_auto_file", the robust way is to get in HKCR\.asm key the default value contents - if it's empty, then search for the "Shell\Open\command" subkey in the same key, otherwise it will be the name of the key with right "Shell\Open\command". HKCR\.asm default value usually contains redirection to "asm_auto_file", so right redirection path is HKCR\asm_auto_file, but the redirection may be other - depends on different things and how user setup the handling of files, like the opening program.
Version 3 works for me, Jochen :t It founds MASM32 package path properly.
it looks like it installed correctly :t
the title bar in the browser flickers continuously - well - it's odd behaviour - the cursor is nutty - lol
it would be nice to have an "installation test" program that assembles using MB
V3 works for me, but a success/fail message would be nice...
In RichMasm, the menu in the title bar overwrites the title bar text - normal behaviour?
Quote from: dedndave on August 24, 2013, 10:23:59 AM
the title bar in the browser flickers continuously - well - it's odd behaviour - the cursor is nutty - lol
There is one spot between System Apps and Help that flickers for me - will have to solve that one day. But no continuous flicker on my machines. What exactly do you see? Which OS, which resolution?
Quoteit would be nice to have an "installation test" program that assembles using MB
Will add my testbed in version 4, now that the 512k limitation is far away.
Quote from: sinsi on August 24, 2013, 12:49:31 PM
V3 works for me, but a success/fail message would be nice...
In RichMasm, the menu in the title bar overwrites the title bar text - normal behaviour?
Not really. Are your title bars centered, or right-aligned? Windows 8, I guess?
The problem here is/was Aero. The idea was to maximise the height of the editor's "real estate", since Assembler is a "vertical language" (note that FF and Thunderbird nowadays do something similar). So I placed the menus inside the caption, and made them also show without clicks (I hate clicking). But then Lingo complained about not seeing them with Vista/Aero (http://www.masmforum.com/board/index.php?topic=9044.msg81497#msg81497), and I found this solution, which is not perfect but works most of the time.
But it should not flicker, and not overwrite titles, of course. Grateful for more detailed descriptions of the problems, folks :icon14:
Bookmarks to the right and listbox are working properly?
On the laptop (win8):
Download masm32 and install...ok
Download and install masmbasic...f**k this, I'm going to use VB
Step 2 needs to be "try to open a .asm file, fail, associate it with something"
Interestingly, SmartScreen blocked masmbasic install but not masm32.
Windows 8 has no aero and centred titles.
Quote from: sinsi on August 24, 2013, 05:34:55 PM
On the laptop (win8):
Download masm32 and install...ok
Download and install masmbasic...f**k this, I'm going to use VB
Step 2 needs to be "try to open a .asm file, fail, associate it with something"
Interestingly, SmartScreen blocked masmbasic install but not masm32.
Windows 8 has no aero and centred titles.
Thanxalot, John. Could you please run the register tests attached here (http://here)? In my installations, qEditor.exe has a HKCR\Applications\qEditor.exe\shell\open\command key, so I wonder where that one is gone...
Re SmartScreen: I have added a manifest to the Setup.exe; does it convince SmartScreen?
Jochen, maybe it will be useful to make the installation path variable? Like "MasmBasic will be installed to ..." and near this a button "Change location..." - for those who have more than one MASM32 installation on different drives.
Could you please run the register tests attached here (http://here)?
Here? Nope :P
John, it's there http://masm32.com/board/index.php?topic=2277.msg23601#msg23601
Fresh install of everything on my win7 box
Before any install ------------------------------------------------------------------------------------------------
C:\Users\User\Desktop>IsMasm32.exe
*** Running Windows 7 Home Premium ***
### Testing asm files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.asm\UserChoice
Progid=[* failed *]
HKCR\.asm
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]
### Testing inc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.inc\UserChoice
Progid=[* failed *]
HKCR\.inc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]
### Testing rc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.rc\UserChoice
Progid=[* failed *]
HKCR\.rc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]
### Finding the path for qEditor.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe [* failed *]
HKCR\Applications\qEditor.exe\shell\open\command [* failed *]
### Finding the path for winword.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe [C:\PROGRA~1\MICROS~3\Office14\WINWORD.EXE]
HKCR\Applications\winword.exe\shell\open\command [* failed *]
Messy, right? Now trying to find the editor elsewhere...
Registry HKCU $edi No luck in HKCU...
Registry HKLM $edi No luck in HKLM...
Registry HKCR $edi No luck in HKCR...
Registry HKCR $edi No luck in HKCR...
FileWrite
$esi C:\Users\User\Desktop\~tmp25081517.asm
$edi C:\Windows\system32\NOTEPAD.EXE
After installing masm32, same as above ---------------------------------------------------------------------------
After associating .asm with qeditor.exe --------------------------------------------------------------------------
C:\Users\User\Desktop>IsMasm32.exe
*** Running Windows 7 Home Premium ***
### Testing asm files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.asm\UserChoice
Progid=[* failed *]
HKCR\.asm
default=[asm_auto_file]
HKCR\asm_auto_file\shell\Open\Command
default=["D:\masm32\qeditor.exe" "%1"]
### Testing inc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.inc\UserChoice
Progid=[* failed *]
HKCR\.inc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]
### Testing rc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.rc\UserChoice
Progid=[* failed *]
HKCR\.rc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]
### Finding the path for qEditor.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe [* failed *]
HKCR\Applications\qEditor.exe\shell\open\command ["D:\masm32\qeditor.exe" "%1"]
### Finding the path for winword.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe [C:\PROGRA~1\MICROS~3\Office14\WINWORD.EXE]
HKCR\Applications\winword.exe\shell\open\command [* failed *]
Messy, right? Now trying to find the editor elsewhere...
Registry HKCU $edi "D:\masm32\qeditor.exe" "%1"
Registry HKLM $edi No luck in HKLM...
Registry HKCR $edi "D:\masm32\qeditor.exe" "%1"
Registry HKCR $edi "D:\masm32\qeditor.exe" "%1"
FileWrite
$esi C:\Users\User\Desktop\~tmp25081536.asm
$edi D:\masm32\qeditor.exe
Your Masm32 root $M32$ D:\masm32\
Your asm files editor $edi D:\masm32\qeditor.exe
One thing I found, once you pick a program not in the "open with" dialog it gets added to HKCR\Applications\the.exe\shell\open\command.
That makes it available in other "open with" dialogs without having to browse. Handy to know.
Alex, so it was there instead of here :biggrin:
jj needs a refresher on using the url tag...
I see that some Volks ask for extra free stuff when your programs are already free.
Jeez.
Your patience is admirable.
Thanxalot, John, that was very helpful :t
Version 5 attached, with testbeds included - just click the "Try one more" link in MbGuide.rtf.
Quote from: sinsi on August 25, 2013, 04:23:50 PM
...
FileWrite
$esi C:\Users\User\Desktop\~tmp25081517.asm
$edi C:\Windows\system32\NOTEPAD.EXE
After installing masm32, same as above ---------------------------------------------------------------------------
After associating .asm with qeditor.exe ..
HKCR\.asm
default=[asm_auto_file]
HKCR\asm_auto_file\shell\Open\Command
default=["D:\masm32\qeditor.exe" "%1"]
HKCR\Applications\qEditor.exe\shell\open\command ["D:\masm32\qeditor.exe" "%1"]
...
Registry HKCU $edi "D:\masm32\qeditor.exe" "%1"
Registry HKLM $edi No luck in HKLM...
Registry HKCR $edi "D:\masm32\qeditor.exe" "%1"
Registry HKCR $edi "D:\masm32\qeditor.exe" "%1"
FileWrite
$esi C:\Users\User\Desktop\~tmp25081536.asm
$edi D:\masm32\qeditor.exe
Version 5 did found MASM32 installation path, but also allowed to change the drive to be installed to, and successfully installed on a different drive :t
successful install :t
the title bar is looking a lot better
however, if i move the mouse to a specific spot between items, the dropdown menu flashes in and out
for example, between Help and AutoCode, there is a spot where the Help menu is repeatedly shown and hidden
Quote from: dedndave on August 25, 2013, 09:20:54 PM
between Help and AutoCode, there is a spot where the Help menu is repeatedly shown and hidden
That's a known bug to be fixed soon :(
@Alex: The first line of the listbox ("matches") can be used to drag it. While the listbox has the focus, cursor left exits to found text, cursor right exits to findbox. One * as in
mov*edx means "find mov and edx in the same line". More stars mean "extend search to n lines".
not trying to hurry you - lol
just wanted to help you wring out the bugzzz
Quote from: jj2007 on August 25, 2013, 09:46:26 PM@Alex: The first line of the listbox ("matches") can be used to drag it. While the listbox has the focus, cursor left exits to found text, cursor right exits to findbox. One * as in mov*edx means "find mov and edx in the same line". More stars mean "extend search to n lines".
Not drag - resize. When bottom edge of listbox is below or sometimes near of bottom edge of the screen, it is not resizable using top edge of a listbox.
oh no, I'm excluded from the best lib on net :(
BTW: eliFoTdaolnwoDLRU?
Quote from: qWord on August 26, 2013, 12:06:55 AM
oh no, I'm excluded from the best lib on net :(
BTW: eliFo...
Obviously, you are
not excluded ;-)
Quote from: dedndave on August 25, 2013, 10:18:16 PM
not trying to hurry you - lol
just wanted to help you wring out the bugzzz
Thanxalot, Dave & Alex & Sinsi :icon14:
I fixed the flickering between the System Apps and Help menus, and a couple of other issues in File/New Masm source, and it should be fine now.
The installer is now on top of this thread. (http://masm32.com/board/index.php?topic=94.0)
nice :t
Hi jj,
I got the "Oops! It seems that MasmBasic is not good for you.."
:icon_eek:
Quote from: anta40 on August 27, 2013, 10:33:19 PM
I got the "Oops! It seems that MasmBasic is not good for you.."
That's mean :biggrin:
What does the attached exe show as output?
This is the output:
Quote
Registry HKCR
$edi No luck in HKCR/App...
$Err$() The operation completed successfully.
Registry HKCU $edi No luck in HKCU...
Registry HKLM $edi No luck in HKLM...
Registry HKCR $edi No luck in HKCR...
FileWrite
$esi C:\Users\CSL-NB-064\Desktop\~tmp28080107.asm
$edi C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE\devenv
.exe
Bye...
Quote from: anta40 on August 28, 2013, 04:08:33 AM
$edi C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE\devenv
Ouch... that's a tough case 8)
I am really tempted to send you googling for Visual Basic, that's what you deserve :P
However, after several glasses of a good red wine I decided to give you a last chance - try again (http://masm32.com/board/index.php?topic=94.0) ;-)
OK, finally it asked for macros.asm
Seems to work, now :biggrin:
Yeah :t
The problem is to find out on which drive the valid Masm32 installation sits (and there should be one, otherwise go google for VB, script kiddie :lol:)
So the installer checks for a qeditor installation, if that fails, it asks how asm files are being opened. And you open them with a prog outside the Masm32 path, that's why it failed. So I added the "last chance" ;)
@echo off
for %%X in (D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%X:\masm32\qeditor.exe set MyDrive=%%X:\
MbInstall %MyDrive%
:P
i know - you don't want a batch file
Great, now I've got a "last" chance! However, a bit strange because I didn't realized that I've had any chance before that one ;)
Quote from: dedndave on August 28, 2013, 10:21:03 PM
i know - you don't want a batch file
That's brute force, Dave :eusa_naughty:
Quote from: qWord on August 29, 2013, 01:45:46 AM
Great, now I've got a "last" chance! However, a bit strange because I didn't realized that I've had any chance before that one ;)
You found the elifo, so you had more than one chance ;-)
Update 30 August:- default buffer for GetRegVal is now 128k
- The Gf...() family returns for index=-1 or no argument the values for the file identified by the last Exist():
GfSize, GfDate$, GfTime$, GfAgeHours, GfAgeMinutes, GfAgeMs, GfLastWrite
GetFiles *.asm ; get all sources in the current folder and its subfolders
xchg eax, ecx ; save #files
For_ ebx=0 To ecx-1
.if GfAgeHours(ebx)<=24 ; pick your latest code
mov esi, Cat$(Files$(ebx)+Space$(20)) ; we simulate LSET
Print Str$("\n#%i ", ebx+1), GfDate$(ebx), ", ", GfTime$(ebx), Spc2$, Str$("%i bytes", edx::GfSize(ebx)) ; edx::eax for QUADWORD size
.endif
Next
Rem - all GetFiles special arrays return a DWORD in eax, except for GfLastWrite, which returns
in xmm0 the ftLastWriteTime FILETIME member of the WIN32_FIND_DATA structure
- GfSize returns the high quad in edx
- Gf....(-1I or Gf...(), i.e. index -1 or no arg: all functions return data for the last Exist()
- GfAge...() is calculated from the moment when GetFiles was launched, except for index=-1, which returns age
relative to the time of the last Exist() call
Update 27 September 2013:
- Fixed a rare bug in Hex$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1198)
- Clip$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1099): the optional parameter is now working properly
- QSort (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175) works now also for dynamic string arrays
- ShEx for those who can't memorise the 5 ShellExecute args (=myself :biggrin:)
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim My$() ; create a dynamic string array
xor ecx, ecx
.Repeat
Let My$(ecx)=Str$("String %i", Rand(20)+1000)
inc ecx
.Until ecx>=20
QSort My$() ; sort all elements allocated so far
For_ ebx=0 To ecx-1
PrintLine Str$("Line %i =\t", ebx), My$(ebx)
Next
if 0 ; New: ShellExecute for dummies
FileWrite "~tmp.txt", Cat$("Hello, it's "+Time$) ; create a text file
ShEx "~tmp.txt" ; you can add e.g. SW_MAXIMIZE if needed
endif
Exit
end start
i know this isn't where it started....
but, Bresenham circles are pretty simple
if you develop an ASM algo, you can plot 8 points with each calculation
for elipses, 4 points - and a little "flip" on the second group of octets
maybe some day, i will play with a full set of Bresenham lines and conics :P
but, this will get you started...
http://people.cs.uchicago.edu/~kaharris/15200/Labs/lab3/circle.html (http://people.cs.uchicago.edu/~kaharris/15200/Labs/lab3/circle.html)
Quote from: dedndave on October 02, 2013, 06:42:00 PM
but, Bresenham circles are pretty simple
You are the expert :t
But are they simpler than this? Or at least faster, in case it matters??
; This application draws a circle to the console
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0) the library
Init Enum 24:xScale, 16:yScale ; define width and height of the circle
push 0 ; start with zero degrees
.Repeat
fld FP4(0.0174533) ; load 360/(2*PI)
fimul stack ; multiply with decimal degrees
fsincos ; get sinus and cosinus simultaneously
push yScale ; create a stack slot containing the vertical scale
fimul stack ; cosinus * yScale
fistp stack ; save to...
pop eax ; ... eax
push xScale ; create a stack slot with the horizontal scale
fimul stack ; sinus * xScale
fistp stack ; save to...
pop ecx ; ... ecx
add eax, yScale+2
add ecx, xScale+3
Locate(ecx, eax)
Print "#"
inc stack
.Until stack>=360 ; loop until the circle is complete
pop eax ; restore stack balance
Locate(xScale/2+7, yScale/2+9)
ConsoleColor cRed
Inkey "Masm32 is great"
Exit
end start
i would guess faster
well - in the old days, they were much faster
don't really know how they compare since ~P4 era
Bresenham circle needs a SQRT, right?
Intel(R) Celeron(R) M CPU 420 @ 1.60GHz (SSE3)
loop overhead is approx. 188/100 cycles
6678 cycles for 100 * Sqrt
11083 cycles for 100 * fsincos
6670 cycles for 100 * Sqrt
11072 cycles for 100 * fsincos
the whole idea behind Bresenham is to use integers, as opposed to floating point math
here is some decent "pseudo-code"
of course, you wouldn't want to use SetPixel
better to calculate DIB section addresses
int x,y,d,r;
y=r;
putpixel(x,y,1);
d=(3-2*r);
while(x<=y)
{
if(d<=0)
d += (4*x+6);
else
{
d = d+4*(x-y)+10;
y--;
}
x++;
putpixel(x,y,1);
putpixel(-x,y,1);
putpixel(x,-y,1);
putpixel(-x,-y,1);
putpixel(y,x,1);
putpixel(-y,x,1);
putpixel(y,-x,1);
putpixel(-y,-x,1);
}
http://www.asksatyam.com/2011/01/bresenhams-circle-algorithm_22.html (http://www.asksatyam.com/2011/01/bresenhams-circle-algorithm_22.html)
Quote from: dedndave on October 03, 2013, 08:38:34 AM
the whole idea behind Bresenham is to use integers, as opposed to floating point math
here is some decent "pseudo-code"
int x,y,d,r;
y=r; <<<<<<<<<<<< assigns garbage
Doesn't fly. But I found one that works great, see attachment (you may have to maximise the console).
For BASIC illiterates: The only MasmBasic instruction is Locate() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1039). If you have a decent Locate macro yourself, you can do it with Masm32 only.
i would assume "y" and "r" are initialized with the radius
not sure how you got bresenham.asm to assemble
end start
start is not defined - i am guessing at the Init call
Quote from: dedndave on October 03, 2013, 05:46:45 PM
not sure how you got bresenham.asm to assemble
Don't be shy, it's just a library, like Masm32 ;-)
Quoteend start
start is not defined - i am guessing at the Init call
Good guess :t
the reason for it not assembling being "start" is undefinded :P
Update 8 October 2013 (download (http://masm32.com/board/index.php?topic=94.0)):
1. Some improvements of the DDE interface to Excel. Inter alia, there is a new xlsRC$() macro:
xlsRC$(1, 2) returns "R1C2"
See detailed example (http://masm32.com/board/index.php?topic=2421.0).
2. Win$() can now take as second argument the ID of a child window:
include \masm32\MasmBasic\MasmBasic.inc
Init
Launch "Notepad.exe \Masm32\include\bignumsdk.inc", SW_MINIMIZE
Delay 200 ; give Notepad 200 ms to get ready
.if WinByTitle("bignumsdk.inc - Note")
xchg eax, ecx ; ecx is the parent, 15 is the ID of the Notepad edit control
wPrint "Content=", wTb$, wWin$(ecx, 15) ; delete the w if you prefer ANSI
ConsoleColor cYellow
wInkey wCrLf$, "Title=", wWin$(ecx)
invoke SendMessage, ecx, WM_CLOSE, 0, 0 ; close Notepad window
.else
Inkey "Notepad not ready - increase the delay?"
.endif
Exit
end start
3. GSL (GNU Scientific Library) example updated (see \Masm32\MasmBasic\GNUSCLIB\DLL\GslExample.asc)
4. New If_ ... Then ... macro (for details see this thread (http://masm32.com/board/index.php?topic=2439.0)):
If_ ebx==123 Then inc ebx : dec eax : call mytest
Update 10 October (download (http://masm32.com/board/index.php?topic=94.0)):
RichMasm can now handle a collection of snippets in one file, as in the attached file containing 40 examples of simple console mode code. In the editor, it is sufficient to select the Init of any examples and then hit F6 to assemble, link & run the example.
EDIT: See update in Reply #147
Update 18 October (download (http://masm32.com/board/index.php?topic=94.0)):
1. Analogous to FileOpen$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1031), MasmBasic has now a comfortable wrapper for SHBrowseForFolder called FolderOpen$():
include \masm32\MasmBasic\MasmBasic.inc ; RichMasm: select Init and hit F6 to test the examples
Init ; FolderOpen$(prompt [, title] [, path] [, BIF flags])
Let esi=FolderOpen$() ; no args = use Windows defaults, start with current folder
Print "Selected: [", esi, "]", CrLf$ ; if the user cancelled, esi will be an empty string
PrintLine "Selected: ", FolderOpen$("Pick a folder:", "Masm32 is great") ; a prompt and a nice title, start with current folder
PrintLine "Selected: ", FolderOpen$("Pick a folder:",, "\Masm32\Examples") ; just a prompt, default title, specific folder
PrintLine "Selected: ", FolderOpen$("9Pick a big folder:") ; a big prompt (font 9), default title, current folder
; prompt, title, path with environment variables, flags
Let esi=FolderOpen$("What is the edit box for?","Locate Office:", "%ProgramFiles%\Microsoft Office", BIF_USENEWUI)
PrintLine esi
PrintLine "Selected folder=[", FolderOpen$("Where are your tools?",, "D:\Masm32\bin"), "]" ; fully qualified initial path
; if you need to check whether the user cancelled, use void and check the zero flag:
void FolderOpen$("5Pick the bin folder, please:","Getting help", "\Masm32\bin") ; use current drive plus initial path
.if !Zero?
MsgBox 0, Launch$(Cat$(eax+"\link.exe /Lib")), "Library manager help:", MB_OK
.else
PrintLine "Nothing selected: [", eax, "]" ; Zero? set = user cancelled, eax points to a Null$
.endif
Exit
end start
2. Minor bugfix: Str$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186)() can now also handle LARGE_INTEGER values properly.
3. See also Monitoring WM_nnnn messages (http://masm32.com/board/index.php?topic=2479.0).
P.S.: There is a pretty fat and pretty stupid SHBrowseForFolder bug in Windows 7 (http://social.msdn.microsoft.com/Forums/vstudio/en-US/a22b664e-cb30-44f4-bf77-b7a385de49f3/shbrowseforfolder-bug-in-windows-7?forum=vcgeneral). Grateful for feedback if FolderOpen$() works properly on all Windows versions from XP upwards. XP and Win7-32 seem to work AFAIK.
Quote from: TWell on October 19, 2013, 02:49:45 AMIf you can give that MamBasic in zip package without installer, i may test it.
I made the installer precisely because many people have forgotten how to extract an archive properly. The installer creates one folder (\Masm32\MasmBasic) and does not modify the registry.
What do you typically do if Adobe or Microsoft or Sun ask you to run a *.msi file? Do you have any reason to trust me less than, ehm, Microsoft?
QuoteQuote from: jj2007 on October 19, 2013, 01:23:04 AM
P.S.: There is a pretty fat and pretty stupid SHBrowseForFolder bug in Windows 7 (http://social.msdn.microsoft.com/Forums/vstudio/en-US/a22b664e-cb30-44f4-bf77-b7a385de49f3/shbrowseforfolder-bug-in-windows-7?forum=vcgeneral). Grateful for feedback if FolderOpen$() works properly on all Windows versions from XP upwards. XP and Win7-32 seem to work AFAIK.
What problem ?
That example code works in my Win7 32/64-bit
Just google for SHBrowseForFolder bug in Windows 7 - many hits, and most mention that it does "not always" scroll down. Your code works fine on XP, can't test it on Win7 right now, but I have seen the no-scroll problem often enough in action on Win7. Need an official Microsoft site? BFFM_SETSELECTION does not work with SHBrowseForFolder on Windows 7 (http://connect.microsoft.com/VisualStudio/feedback/details/518103/bffm-setselection-does-not-work-with-shbrowseforfolder-on-windows-7)
Quote from: jj2007 on October 19, 2013, 03:24:55 AM
Just google for SHBrowseForFolder bug in Windows 7 - many hits, and most mention that it does "not always" scroll down. Your code works fine on XP, can't test it on Win7 right now, but I have seen the no-scroll problem often enough in action on Win7. Need an official Microsoft site? BFFM_SETSELECTION does not work with SHBrowseForFolder on Windows 7 (http://connect.microsoft.com/VisualStudio/feedback/details/518103/bffm-setselection-does-not-work-with-shbrowseforfolder-on-windows-7)
Thanks for that link, now i see that problem, it starts showing from Destop and selected folder isn't visible as in WinXP, so no scrolling to that.
the MasmBasic installer is benign - and a good way to go
it can be a little confusing to install it manually
Quote from: TWell on October 19, 2013, 05:54:44 AMHere is code example to fix that problem:
Thanks, I know that example, and I wouldn't have posted a new MasmBasic version if I had not already fixed the problem. Still, grateful for feedback if MB OpenFolder$() works, because I took a slightly different road (the code you posted failed occasionally on my Win7-32 system).
Attached an exe for testing. The source is lines 372ff of MbFuide.rtf (also included, you have it already at \Masm32\MasmBasic\MbGuide.rtf in case you downloaded MasmBasic (http://masm32.com/board/index.php?topic=94.0)).
Quote from: jj2007 on October 19, 2013, 08:33:56 AM
Still, grateful for feedback if MB OpenFolder$() works, because I took a slightly different road (the code you posted failed occasionally on my Win7-32 system).
Attached an exe for testing. The source is lines 372ff of MbFuide.rtf (also included, you have it already at \Masm32\MasmBasic\MbGuide.rtf in case you downloaded MasmBasic (http://masm32.com/board/index.php?topic=94.0)).
OpenFolder works nicely in Win7 64-bit.
Avast don't let me download that zip.
BYE
Major update of MasmBasic, 24 October 2013 (download (http://masm32.com/board/index.php?topic=94.0)):
1. Put multiple formats on the clipboard (full example attached, MS Word should be running):
SetClip #start ; ---- set multiple clipboard formats ----
SetHtmlClip$ "Text in <font color='blue'>HTML</font> format" ; for Thunderbird and Excel
SetClip 100, CF_BITMAP ; 100 = ID of bitmap resource
SetClip$ offset txTest, CF_RTF ; Rich Text Format
SetClip$ wRes$(123) ; use resource string #123, "This is a sub-title" in Russian (Unicode)
SetClip$ "This is ANSI text"
SetClip #end ; ---- end of multiple clipboard formats ----
2. Improved DDE to Excel macros, inter alia for writing Unicode (the real thing, e.g. Chinese etc from resources), pasting HTML format etc. - screenshot (example attached) below.(http://www.webalice.it/jj2006/pics/Masm2Excel.png)
P.S.: The attached MbSnippets.asc, when opened in \Masm32\MasmBasic\RichMasm.exe, allows to build & run over 40 "snippets", i.e. short examples showing what the MB macros can do. Just click one of the Init entries in the listbox (or select an Init by hand), then hit F6 to see the result. Test it, for example, with the ## Unicode with wRes$ ## snippet in line 468.
Update 30 October 2013 (download (http://masm32.com/board/index.php?topic=94.0)):
StackBuffer
MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT
LOCAL rc:RECT, sbuf1, sbuf2, sbuf3, whatever[100]:BYTE
; optional: ClearLocals ; first line after the LOCALs
mov sbuf1, StackBuffer(100000) ; allocate two fat buffers, and make sure
mov sbuf2, StackBuffer(4000h) ; they are 16-byte aligned for use with SSE2
invoke GetFileSize, hFile, 0 ; you may use a register or any other variable to specify the buffer size
mov sbuf3, StackBuffer(eax, nz) ; option nz means "no zeroing" - much faster (the buffer end is zeroed anyway)
PrintLine "Start buffer 1:", Tb$, Hex$(sbuf1)
PrintLine "Start buffer 2:", Tb$, Hex$(sbuf2)
StackBuffer() ; release all buffers (sb without args = free the buffer)
ret
MyTest endp
Rem - buffer size is limited by start address of stack; normally, you can use close to one MB
- the start address is aligned to 64 bytes for use with SIMD instructions
- you can use StackBuffer anywhere (not only at proc start & end), but make sure esp is unchanged
- StackBuffer zero-inits the buffer, unless option nz is specified (much faster)
- with option nz, only the end of the buffer (+/- 2 bytes, one DWORD) is zeroed
- can be combined with ClearLocals
- StackBuffer does the stack probing for you; up to about half a megabyte, it is significantly faster than HeapAlloc
EDIT: Version MbSetup30Oct2013d.zip fixes a problem with the Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) timeout. In the new version, Launch$() throws an error when there is no read activity for more than n milliseconds, which is a better behaviour with apps that give slow feedback in bits and pieces, e.g. zippers or even ML.exe (the old Launch$() version stopped when the timeout was reached overall).
Example:
a) slowly printing app:
include \masm32\MasmBasic\MasmBasic.inc
Init
push 15
.Repeat
Print Str$("sp%i ", stack)
mov ecx, 100
.if stack==5 || stack==10
mov ecx, 2000 ; the app "chokes" two seconds with element 5+10
.endif
invoke Sleep, ecx
dec stack
.Until Sign?
Print "BYE", 13, 10 ; No inkey, please
Exit
end start
b) Launcher:
include \masm32\MasmBasic\MasmBasic.inc
Init
PrintLine "## Launch Nr. 1 ##"
Let esi=Launch$("SlowPrint", SW_RESTORE, 1000) ; SlowPrint is an app that ... prints slowly
PrintLine "First attempt, timeout=1000: ", Tb$, esi
PrintLine "## Launch Nr. 2 ##"
Let esi=Launch$("SlowPrint", SW_RESTORE, 1500)
PrintLine "Second attempt, timeout=1500: ", Tb$, esi
PrintLine "## Launch Nr. 3 ##"
Let esi=Launch$("SlowPrint", SW_RESTORE, 2000)
Inkey "Third attempt, timeout=2000: ", Tb$, esi
Exit
end start
Output:
## Launch Nr. 1 ##
First attempt, timeout=1000: La$?
## Launch Nr. 2 ##
Second attempt, timeout=1500: La$?
## Launch Nr. 3 ##
Third attempt, timeout=2000: sp15 sp14 sp13 sp12 sp11 sp10 sp9 sp8 sp7 sp6 sp5 sp4 sp3 sp2 sp1 sp0 BYE
:t Impressive, it become more and more usefull. I'll use MASM BASIC started from now and forever.
What does it is mean ? "D:\Masm32\Include\MasmBasic.inc(168) : error A2052: forced error"
My other project did not yield this error, what causing it?
Quote from: Farabi on November 08, 2013, 06:16:32 PM
What does it is mean ? "D:\Masm32\Include\MasmBasic.inc(168) : error A2052: forced error"
My other project did not yield this error, what causing it?
Hi Farabi,
What else does the error message say? To which source code line does it refer? Can you post these lines (+/- 10 lines)?
There are several "forced" errors in the library, some because you can't use the old ML 6.14 assembler, others because of syntax problems...
There was a nasty little bug since the introduction of ArraySet (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1129)():
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim My3Pts(5) As REAL4 ; create an array with 3 XY pairs, i.e. 6 elements (0 .. 5)
ArraySet My3Pts() = 1.0, 100.0, 2.0, 300.0, 4.0, 150.0 ; assign XY values
Inkey "ok"
Exit
end start
The macro started one step above its HeapAlloc'ed area, and thus on rare occasions could cause an exception. This bug showed up with REAL4 and REAL8 but not with DWORD arrays.
Apologies - it's fixed now, download here (http://masm32.com/board/index.php?topic=94.0)
Other changes concern only DosBasic (http://masm32.com/board/index.php?topic=1855.0), the little 16-bit brother of MasmBasic.
A small addition for version 11.11.2013 (download (http://masm32.com/board/index.php?topic=94.0)): CL$(?) returns the number of commandline arguments.
Note that CL$(0), i.e. the name of the executable, is not counted here, which is a minor inconsistency with regard to
Dim My$(9)
Print Str$("There are %i elements in the array\n", My$(?))
returning There are 10 elements in the array, i.e. 0...9
Update 11 December 2013:
- a completely redesigned installer (well, under the hood ;))
- Qtrim$():
Let My$=Qtrim$(Chr$(9, ' "quoted" ', 13, 10)) ; returns quoted
Let My$=Qtrim$(CL$()) ; same for complete quoted commandline
- Extract$() has a new flag, xsEscape, meaning translate \n to CrLf and \t to a tab:
; exclude left pattern, case-insensitive, trim whitespace, right pattern is default aka CrLf; in short: grab the line after =
xsDefault=xsExcL or xsCaseI or xsTrim or xsEscape
Let Title$=Extract$(esi, "title=")
.. where esi is a buffer containing this text:
This is a simple text file, and we want to extract the part below after "=":
Title=Hello\nWorld\nhow are you?
Let title$=Extract$(esi, "Title") will yield only the hello world part (in three lines), provided the right flags are set. For details, see \Masm32\MasmBasic\MbGuide.rtf
Several new snippets were added, see attachment. When opened with RichMasm, each of them can be built and run by selecting Init and hitting F6. This works also when the Find string is Init, and the user selects one of the entries in the listbox. In a way, this is multiple projects in a single source file ;)
Hi jj,
I think there's a bug with the installer.
After I selected C:\masm32\macros\macros.asm, I could see this on the installer:
"The MasmBasic library will be installed to La$?"
"Can't create destination folder
La$?"
Hi anta,
"La$?" is what Launch$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047)("whatever.exe") returns if whatever.exe hangs and/or a timeout occurs. Apparently the default timeout is too short - I will fix this asap.
Thanks a lot for the feedback,
jj
EDIT: It's fixed, see version 11 Dec 2013b
There is a problem with Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186) when used with .data section arrays - it will not digest e.g. Str$(MyArray[3*REAL8]):
include \masm32\MasmBasic\MasmBasic.inc
.data
MyArray REAL8 1.23, 4.56, 7.89, 9.87
Init
Print Str$("Element 0 is %3f\n", MyArray) ; Str$(REAL8_var) works, but only for element zero
el1 equ MyArray[1*8] ; workaround for other elements - no <brackets> please
Print Str$("Element 1 is %3f\n", el1)
mov ecx, offset MyArray+1*REAL8 ; use a register to access array elements
Print Str$("Element 2 is %3f\n", real8 ptr [ecx+8]) ; OK if exactly one blank between ptr and [
; no problems with Basic-style arrays (byte/word/dword/qword/R4/r8/r10):
Dim MyR8(3) As REAL10 ; create an array of long doubles (same for REAL4, REAL8)
fldpi
fstp MyR8(3) ; put PI into element 3
Print Str$("Element 3 is %Jf\n", MyR8(3))
Inkey "ok"
Exit
end start
I had found a fix, but unfortunately it chokes with JWasm, so for the time being, and if you really need it, use the equate.
With MasmBasic of 22 December 2013, you can print unsigned qwords like 12345678901234567890:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
MyLongLong LONGLONG 12345678901234567890
MyDword LONG 1234567890
MyWord WORD 12345
MyByte BYTE 123
MySingle REAL4 12345678901234567890.0
MyDouble REAL8 12345678901234567890.0
MyR10 REAL10 1234567890123456789012.0
Init ; ## deb and the Art of Type Checking ##
mov eax, MyDword
mov bx, MyWord
mov cl, MyByte
fldpi ; PI, 3.14159
fldl2e ; Log2(e), 1.4427
fldlg2 ; Log10(2), 0.3013
movlps xmm0, MyLongLong
movlps xmm1, MyDouble
DefNum 16 ; set precision (only f:xmm1 affected)
deb 4, "Any type missing?", u:MyLongLong, u:xmm0, f:xmm1, ST(0), ST(1), ST(2), MyDword, MyWord, MyByte, cl, bx, eax, MySingle, MyDouble, MyR10
Exit
end start
Output:
Any type missing?
u:MyLongLong 12345678901234567890
u:xmm0 12345678901234567890
f:xmm1 1.234567890123457e+19
ST(0) 0.301029995663981195
ST(1) 1.44269504088896341
ST(2) 3.14159265358979324
MyDword 1234567890
MyWord 12345
MyByte 123
cl 123
bx 12345
eax 1234567890
MySingle 1.234568e+19
MyDouble 1.234567890123457e+19
MyR10 1.23456789012345679e+21
This example is included in the attached MbSnippets.asc
MasmBasic 28 Dec 2013 supports Insert and Delete for numerical arrays:
Init ; we create several numeric arrays,
Dim MyByte() As BYTE ; from byte to ...
Dim MyWord() As WORD
Dim MyDw() As DWORD
Dim MyQw() As QWORD ; ... qword
Dim MyRc() As RECT ; any other structure would work, too
Dim My$() ; plus one string array
call FillTheArrays ; fill the arrays with some nice values
call PrintTheArrays ; display the original values
xor ecx, ecx ; we test different index positions:
Delete MyQw(ecx) ; 0 reg32
Delete MyDw(ecx+1) ; 1 reg plus offset
Delete MyWord(gct2) ; 2 global var
Delete MyByte(3) ; 3 immediate
Delete MyRc(ecx+4) ; 4
Delete My$(ecx+3) ; 3
PrintLine CrLf$, "Elements 0 1 2 3 4 3 deleted:"
call PrintTheArrays ; display the modified arrays
Output:
Qword Dword Word Byte rcLeft rcBottom (8 elements)
0 00000000 00000000 00000000 0000 00 00000000 1000 String #0
1 11111111 11111111 11111111 1111 11 11111111 1001 String #1
2 22222222 22222222 22222222 2222 22 22222222 1002 String #2
3 33333333 33333333 33333333 3333 33 33333333 1003 String #3
4 44444444 44444444 44444444 4444 44 44444444 1004 String #4
5 55555555 55555555 55555555 5555 55 55555555 1005 String #5
6 66666666 66666666 66666666 6666 66 66666666 1006 String #6
7 77777777 77777777 77777777 7777 77 77777777 1007 String #7
Elements 0 1 2 3 4 3 deleted:
Qword Dword Word Byte rcLeft rcBottom (8 elements)
0 11111111 11111111 00000000 0000 00 00000000 1000 String #0
1 22222222 22222222 22222222 1111 11 11111111 1001 String #1
2 33333333 33333333 33333333 3333 22 22222222 1002 String #2
3 44444444 44444444 44444444 4444 44 33333333 1003 String #4
4 55555555 55555555 55555555 5555 55 55555555 1005 String #5
5 66666666 66666666 66666666 6666 66 66666666 1006 String #6
6 77777777 77777777 77777777 7777 77 77777777 1007 String #7
7 00000000 00000000 00000000 0000 00 00000000 0
Elements 3 4 5 6 7 6 inserted:
Qword Dword Word Byte rcLeft rcBottom (8 elements)
0 11111111 11111111 00000000 0000 00 00000000 1000 String #0
1 22222222 22222222 22222222 1111 11 11111111 1001 String #1
2 33333333 33333333 33333333 3333 22 22222222 1002 String #2
3 00000000 00000000 44444444 4444 44 33333333 1003 String #4
4 44444444 44444444 00000000 5555 55 55555555 1005 String #5
5 55555555 55555555 55555555 0000 66 66666666 1006 String #6
6 66666666 66666666 66666666 6666 00 77777777 1007
7 77777777 77777777 77777777 7777 77 00000000 0 String #7
Testbed attached (*.asc opens with \Masm32\MasmBasic\RichMasm.exe)
Update 8 January 2014: (http://masm32.com/board/index.php?topic=94.0)
- fixed a problem with MyNumericArray(?) and non-autoexpanding arrays (when used with ArrayRead (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1179), ? erroneously returned the initial count only)
- fixed a problem with Str$() and signed QWORDs
- introduced the option to leave a MovVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1203) result on the FPU in ST(0):
MovVal ST(0), "3.141592653589793238"
Update 11 January (http://masm32.com/board/index.php?topic=94.0) fixed a minor problem with Trim$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1164) and introduced voidTrue and voidFalse macros (see Assert (http://masm32.com/board/index.php?topic=2831.0) and \Masm32\MasmBasic\MbGuide.rtf):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim My$() ; create a string array
mov ecx, Chr$(" Hello ") ; you can't use eax or edx ...
Let My$(0)=Trim$(ecx) ; ... when assigning to an array,
Let My$(1)=Str$(123)+Trim$(ecx)+Str$(456) ; but ecx is persistent
Inkey "My$(0)=[", My$(0), "]", CrLf$, "My$(1)=[", My$(1), "]"
Exit
end start
Output:
My$(0)=[Hello]
My$(1)=[123Hello456]
It seems so :P
I've been fighting with pipes for a while, and google says I'm in good company - it's messy. After a lot of testing, it seems PeekNamedPipe is the best way to decide when to leave the read loop, so the new Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) uses this internally.
The sample below launches a console app that returns strings unsteadily, i.e. normally it takes around 50ms to see the next output, but occasionally it chokes for a whole second. This is a typical behaviour e.g. of archivers, and the coder must impose a timeout to decide if the delay is OK or if the child process hangs. In other words, the third arg of Launch$() is now the tolerated inactivity period:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
PrintLine "## Launching SlowPrint.exe ##" ; slowprint.exe must be in the same folder
Let esi=Launch$("SlowPrint", SW_MINIMIZE, 1000) ; max allowed inactive period of child process is 1000ms
PrintLine Str$("\nFirst attempt, timeout=1000: exit code=%i\n", ExitCode($)), "Output:", Tb$, esi
Let esi=Launch$("SlowPrint", SW_MINIMIZE, 1020)
PrintLine Str$("\nSecond attempt, timeout=1020: exit code=%i\n", ExitCode($)), "Output:", Tb$, esi
Let esi=Launch$("SlowPrint", SW_MINIMIZE, 1040)
PrintLine Str$("\nThird attempt, timeout=1040: exit code=%i\n", ExitCode($)), "Output:", Tb$, esi, CrLf$
Inkey "bye"
Exit
end start
Output:
## Launching SlowPrint.exe ##
First attempt, timeout=1000: exit code=259
Output: La$?
Second attempt, timeout=1020: exit code=0
Output: sp15 sp14 sp13 sp12 sp11 sp10 sp9 sp8 sp7 sp6 sp5 sp4 sp3 sp2 sp1 sp0 2656 ms
Third attempt, timeout=1040: exit code=0
Output: sp15 sp14 sp13 sp12 sp11 sp10 sp9 sp8 sp7 sp6 sp5 sp4 sp3 sp2 sp1 sp0 2656 ms
MasmBasic update of 17 January: (http://masm32.com/board/index.php?topic=94.0)
The snippets file is now integrated into the package, see the "try 50+ snippets" link in the Hello World example.
Latest feature is a much easier handling of strings (e.g. paths) in structures:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
MyStruct STRUCT
xText20$ db 20 dup(?) ; 20 bytes of text
xDword dd ? ; a dword, just for fun
xText4$ db 4 dup(?) ; more text
xText1$ db 1 dup(?) ; and one byte of text
MyStruct ENDS
.data?
myS MyStruct <>
Init
; assign strings with Let:
Let myS.xText20$="This string can take a maximum of 20 chars"
Let myS.xText4$="That one can take only 4 chars"
Let myS.xText1$="1 char only..."
; print the strings:
PrintLine "{", myS.xText20$, "}"
PrintLine "{", myS.xText4$, "}"
Print "{", myS.xText1$, "}"
Exit
end start
Output:
{This string can take}
{That}
{1}
EDIT: Now it works also for structures defined with SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015).
include \masm32\MasmBasic\MasmBasic.inc
PATHS STRUCT
path1 db MAX_PATH dup(?)
path2 db MAX_PATH dup(?)
PATHS ENDS
SetGlobals MyPaths:PATHS ; define a global structure
Init
SetGlobals ; let ebx point to the global memory
mov ecx, CurDir$(0) ; get the current folder (0=no backslash)
Let MyPaths.path1=ecx
Let MyPaths.path2=MbExeFolder$ ; assign the folder from which the exe was started
PrintLine "Path1=", MyPaths.path1
Inkey "Path2=", MyPaths.path2
Exit
end start
But MasmBasic will :biggrin:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion"
PrintLine "Checking ", esi
GetRegKeyArray esi, Lev1$(), LastMod1()
For_ ecx=0 To eax-1
.if Age(LastMod1(ecx), d)<=31 ; changed in the last 31 days
Print Str$("\nKey %i\t", ecx), fDate$(LastMod1(ecx)),\
", ", fTime$(LastMod1(ecx)), Tb$, "[", Lev1$(ecx), "]"
GetRegKeyArray Cat$(esi+"\"+Lev1$(ecx)), Lev2$(), LastMod2()
For_ ebx=0 To eax-1
.if Age(LastMod2(ebx), h)<=24*3 ; changed in the last 3 days
Print CrLf$, "- ", Tb$, fDate$(LastMod2(ebx)),\
", ", fTime$(LastMod2(ebx)), Tb$, Lev2$(ebx)
.endif
Next
.endif
Next
Exit
end start
Sample output:
Checking HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion
Key 7 23.01.2014, 07:11:19 Explorer
Key 10 23.01.2014, 15:27:22 Group Policy
- 23.01.2014, 15:42:00 Regedit
- 23.01.2014, 11:35:39 SysTray
Key 11 23.01.2014, 07:11:30 HomeGroup
Key 13 08.01.2014, 07:11:42 Internet Settings
Key 18 23.01.2014, 14:08:57 Run
Key 19 23.01.2014, 07:11:20 RunOnce
Source & exe attached - the very latest version of MasmBasic is required.
EDIT: Typo Lev1$(ebx) corrected - it must be Lev1$(ecx), of course.
Update 25 January: For ... Next loops will now not enter the first iteration if begin>end, in line with (most if not all) other Basic dialects. Example (from \Masm32\MasmBasic\Res\MbSnippets.asc):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init ; ## nested For ... Next loops ##
mov eax, 3
For_ ebx=0 To eax-1 ; 0...2 (using eax is allowed here)
; first iteration is 1 to 0 and will be rejected (2*ebx=0, 2, 4, ...)
For_ ecx=1 To ebx+ebx
call MyTest
Next
Print
Next
Inkey "ok"
Exit
MyTest proc
LOCAL ct
For_ ct=0 To 9
Print "*"
Next ct
Print Str$("\tebx=%i, ", ebx), Str$("ecx=%i\n", ecx)
ret
MyTest endp
end start
Output:
++++++++++ ebx=1, ecx=1
++++++++++ ebx=1, ecx=2
++++++++++ ebx=2, ecx=1
++++++++++ ebx=2, ecx=2
++++++++++ ebx=2, ecx=3
++++++++++ ebx=2, ecx=4
31 January 2014 - improved Dll & Declare:
include \masm32\MasmBasic\MasmBasic.inc ; include this library
.data
MyLongLong LONGLONG 12345678901234567890
Init ; initialise the app
Dll "shimgvw" ; load the Windows Picture and Fax Viewer Library
Declare void ImageView_Fullscreen, 4 ; ImageView_Fullscreen expects 4 dwords but returns nothing useful, therefore void
ImageView_Fullscreen(0, 0, wCL$(1), SW_SHOW) ; we need the wide version of the commandline arg
Err$(1) ; there is no retval, so we have to test for errors
Dll "msvcr100"
Declare void printf, C:? ; don't return anything, C calling convention, vararg
printf(cfm$("MyLongLong is %llX aka %llu\n"), MyLongLong, MyLongLong) ; MyLL as hex and decimal figure
Print "MyLongLong is ", Hex$(MyLongLong), Str$(" = %u\n", MyLongLong) ; standard MasmBasic syntax, for comparison
Dll "NtDll"
Declare RtlRandomEx, 1 ; one arg, _Inout_ PULONG Seed
Dll "ntoskrnl.exe"
Declare RtlRandomExNtos, 1 Alias "RtlRandomEx" ; same but native API - will crash in user mode
PrintLine "A random number: ", Hex$(RtlRandomEx(addr MyLongLong))
Exit ; do a clean exit, inter alia FreeLibrary
end start
- Dll performs LoadLibrary, Declare initialises the macro with GetProcAddress, Exit frees the libraries
- use Declare void SomeFunction, ... if you don't need the return value
- use Declare SomeFunction, C:3 for C calling convention with three args
- use Declare SomeFunction, C:? for C calling convention with a variable number of arguments
- the Alias keyword allows to declare a self-defined name; use in case of "already defined" errors
- use Declare #123=SomeFunction, 2 to access a function by ordinal number; then mov ecx, SomeFunction(arg1, arg2)
- if the function cannot be found, try the decorated name:
Declare _SomeFunction@12, C:3 ; three args, C calling convention
then use e.g. mov ecx, SomeFunction(arg1, arg2, arg3)
- do not use Dll & Declare for the static libraries of the Masm32 package (user32, kernel32, ..., see Masm32rt.inc (http://\masm32\include\masm32rt.inc))
- up to 9 libraries can be loaded
Update 26 February (download (http://masm32.com/board/index.php?topic=94.0)):
- Declare accepts now entire structures:
Dll Cat$(MbExeFolder$+"ZipDll\Zip32")
Declare ZpArchive, 1 ; the arg is a ZCL structure with three DWORDs
- the second new feature is in response to questions how to protect one's code. It concerns the RichMasm editor, which has a new entry in the Edit & Format menu:
include \masm32\include\masm32rt.inc
.code ; You can bet that Olly cannot recognise the code sequence which creates this string!
start:
exit
end start
Now select the "You can bet..." part and click on Edit & Format, Obscure string.
Result:
include \masm32\include\masm32rt.inc
.code ; You can bet that Olly cannot recognise the code sequence which creates this string!
start:
; ---- start ----
call @F
@obs$ dd 0DB771968h,0DB567E06h,0B2240A75h,09257631Dh,0E6771078h,09216750Ah,0F1361D69h,0985E6A49h,0FD3D042Ch,0884C615Fh,0A8290530h,
0CB096058h,0BF29052Bh,0D6476244h,0B5221064h,0C14D7E0Ah,0A02E5E73h,0CC421153h,0B8237927h,098571C45h,0B8397D26h,0984C127Fh
@@: pop edx
mov ecx, sizeof @obs$/4
.Repeat
mov eax, [edx]
xor eax, [edx-4]
add edx, 4
push eax
dec ecx
.Until Zero?
PrintLine esp ; that one is for MasmBasic, but...
print esp ; ... Masm32 print works fine, too
add esp, sizeof @obs$
; ---- end ----
exit
end start
I guess the code is self-explanatory for those who need this feature :P
You could try a tool in the masm32 bin directory called "mangle.exe". Once the string is assembled into the binary its a genuine joy to track it down. :P
Quote from: hutch-- on February 26, 2014, 10:53:11 AM
You could try a tool in the masm32 bin directory called "mangle.exe". Once the string is assembled into the binary its a genuine joy to track it down. :P
It's in \Masm32, not in \bin, and it works fine :t
My code is shorter, though, and confuses Olly a lot more (and no need to mfree).
Attached a test piece. The exe has two int 3s for use with Olly or any other debugger.
The source requires MasmBasic (http://masm32.com/board/index.php?topic=94.0), of course.
Update 1 March with two minor bugfixes: (http://masm32.com/board/index.php?topic=94.0)
- Launch (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1045) could give a wrong ExitProcess return value
- buffers created with SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) choked when invoked as e.g. MsgBox 0, addr buffer, ...
EDIT: Version SetupMasmBasic27March14.zip (http://masm32.com/board/index.php?topic=94.0) fixes a bug that prevented \Masm32\MasmBasic\Res\XlsViewer.asc to send text to Excel.
Update 27 March 2014:
- ArrayMerge does what the name says, it merges two string arrays:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init ; ## merge two string arrays ##
Dim Dest$()
Dim Src$()
xor ecx, ecx
.Repeat
Let Dest$(ecx)=Str$("Destination #%i", ecx)
Let Src$(ecx)=Str$("Source #%i", ecx)
inc ecx
.Until ecx>=5
ArrayMerge Dest$(), Src$()
push Dest$(?) ; put the new element counter on the stack
xor ecx, ecx
.Repeat
Print Str$("\n#%i\t", ecx), Dest$(ecx) ; see dest 0...4, then source 0...4
inc ecx
.Until ecx>=stack
pop eax
Exit
end start
Output:
#0 Destination #0
#1 Destination #1
#2 Destination #2
#3 Destination #3
#4 Destination #4
#5 Source #0
#6 Source #1
#7 Source #2
#8 Source #3
#9 Source #4
- Str$() can now handle leading spaces or zeros:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init ; ## leading spaces for Str$() ##
Print Str$("\nA number: %__i", 1)
Print Str$("\nA number: %__i", 12)
Print Str$("\nA number: %__i", 123)
Print Str$("\nA number: %000i", 1)
Print Str$("\nA number: %000i", 12)
Print Str$("\nA number: %000i", 123)
Exit
end start
Output:
A number: 1
A number: 12
A number: 123
A number: 0001
A number: 0012
A number: 0123
Installing the latest version
I see the menu problem is still there, in my case the text is yellow and unreadable.
Clicking one seems to stop it from working from then on too, unless you click another menu..
The crash box is the equivalent to MS Word auto recovery. It happens when user exited an edit session in an, ehm, unusual way. Normally it shouldn't happen, RichMasm is pretty stable, but a forced reboot could cause that, for example. Or killing the editor with Task Manager. I usually click Yes.
Re menus, yes the yellow-brownish font was the compromise for Vista Aero, and I also don't like it. Do the menus work at least? And can you reproduce the hanging?
Update 15 April (download here (http://masm32.com/board/index.php?topic=94.0)):
QuoteLaunch
...
- the default timeout for a "normal" Launch is ten seconds; if you mostly need asynchronous launches,
you can modify this value with e.g. SetLaunchTimeout 1 (in ms)
And this solved also the little problem with the ten seconds "hanging" of RichMasm (http://masm32.com/board/index.php?topic=3108.0) ;-)
Update 18 April (http://masm32.com/board/index.php?topic=94.0) features some improvements of the registry functions:
- SetReg64 allows to read the registry on a 64-bit system
- GetRegVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1214) returns now
1. a pointer to the string or the data in eax
2. the type (REG_DWORD ...) in edx
3. REG_QWORD values in xmm0; same for the first 16 bytes of REG_BINARY
- finally, xmm0 is now a valid argument for the fDate$() and fTime$() macros.
Below an example which reads the "Safer" keys and displays first the "official" LastModified value, and second, the real modification date and time as reported by the registry's timestamp.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="HKLM\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers\0\Hashes\"
GetRegKeyArray esi, My$(), LastMod()
.if eax
push eax
xor ecx, ecx
PrintLine esi, CrLf$, "... modified according to LastModified value:"
.Repeat
; GetRegVal returns the LastModified REG_QWORD in xmm0:
void GetRegVal(Cat$(esi+My$(ecx)), "LastModified", 0)
PrintLine fDate$(xmm0, "dd MMMM yyyy "), Tb$, fTime$(xmm0), Spc2$, My$(ecx)
inc ecx
.Until ecx>=stack
xor ecx, ecx
PrintLine CrLf$, "Hashes modified according to registry timestamp:"
.Repeat
PrintLine fDate$(LastMod(ecx), "dd MMMM yyyy "), Tb$, fTime$(LastMod(ecx)), Spc2$, My$(ecx)
inc ecx
.Until ecx>=stack
pop eax
.endif
Inkey Str$("\n%i keys found\n", eax)
Exit
end start
Source & exe attached. The second attachment (RADAR (http://windowsir.blogspot.it/2011/09/registry-stuff.html)) lists all software on your PC that suffered from a heap leak. Very interesting, but it works only on Windows 7 and higher, so right now I can't test it. Please post some example output :icon_mrgreen:
QuotePlease post some example output
0 keys found
0 keys found
:biggrin:
Hi sinsi,
Yesterday I tested it on Win7, and got the Who's Who of the software industry, Acrobat.exe on top... do you see HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\ in regedit, or is it simply absent?
But wait - you are on Win8-64, right? This could do the trick:
Init
SetReg64
Let esi="HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\"
GetRegKeyArray esi, Radar$(), Modified()
Modified package attached.
BTW first tests with SetReg64 failed miserably until I discovered that KEY_WOW64_32KEY was 100h, not 100 as set in Windows.inc (see also Don57,
windows.inc KEY_WOW64_32KEY def'n error (http://masm32.com/board/index.php?topic=1404.0))
:t
HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\
... modified according to Modifiedified value:
03 March 2014 00:00:00 BurnoutParadise.exe
14 May 2013 05:14:28 CNC4.game
21 January 2014 03:50:13 CoDWaW LanFixed.exe
04 August 2013 23:56:45 DllHost.exe
03 February 2014 01:05:19 eduke32.exe
01 April 2014 08:45:25 firefox.exe
09 February 2014 11:13:45 GasGuzzlers.exe
15 September 2013 08:33:07 IEXPLORE.EXE
27 June 2013 09:35:22 Need for Speed The Run.exe
07 January 2014 06:52:41 NFS11.exe
05 April 2014 06:26:25 NFS13.exe
20 November 2013 05:35:14 shift2u.exe
22 December 2013 00:19:09 simnow.exe
30 April 2013 08:29:50 Stronghold3.exe
10 April 2014 06:43:19 TiWorker.exe
15 keys found
Thanks :biggrin:
Nice to see two competing browsers here. Would be even nicer to see how much they are leaking ;-)
01 April 2014 08:45:25 firefox.exe
15 September 2013 08:33:07 IEXPLORE.EXE
Jochen,
HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\
... modified according to Modifiedified value:
06 Februar 2014 00:00:00 ChessProgram13.exe
16 Januar 2014 19:00:27 firefox.exe
07 Oktober 2013 00:06:34 FlashPlayerPlugin_11_8_800_168.exe
12 Januar 2014 16:20:51 FlashPlayerPlugin_11_9_900_170.exe
17 Februar 2014 23:10:44 FlashPlayerPlugin_12_0_0_44.exe
02 April 2014 11:19:31 FlashPlayerPlugin_12_0_0_77.exe
6 keys found
Gunther
Thanks. Gunther. How dare you run such old versions of Flash?? I haven't rebooted my machine today, but I am sure Adobe has a better version for us, with better performance and less risks, grosses Indianerehrenwort ;-)
Here results from a rarely used notebook with no Internet connection:
HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\
... modified according to ModifiedValue:
05 January 2014 00:00:00 firefox.exe
20 March 2014 17:31:46 InsertDeleteNumArrays.exe
10 November 2012 23:13:25 OllyDbg.exe
04 January 2014 20:15:58 svchost.exe_netsvcs
10 November 2012 20:37:00 TrustedInstaller.exe
Hint: One of these leaky apps is from a well-known hobby coder testing his library ;-)
:biggrin:
Flash is not the problem I have, its the McCafee crap that is bundled with it. I have to uninstall it every time Flash wants an upgrade.
Quote from: hutch-- on April 19, 2014, 08:35:50 PM
:biggrin:
Flash is not the problem I have, its the McCafee crap that is bundled with it. I have to uninstall it every time Flash wants an upgrade.
that is the point.
Gunther
ArrayMerge had a problem with differently sized arrays. It is fixed in version 22 April 2014. (http://masm32.com/board/index.php?topic=94.0)
The code below will now work correctly.
include \masm32\MasmBasic\MasmBasic.inc
Init ; ## merge two string arrays ##
Dim Dest$()
Dim Src$()
xor ecx, ecx
.Repeat
.if ecx<3
Let Dest$(ecx)=Str$("Destination #%i", ecx)
.endif
Let Src$(ecx)=Str$("Source #%i", ecx)
inc ecx
.Until ecx>=10
ArrayMerge Dest$(), Src$()
push Dest$(?) ; put the new element counter on the stack
xor ecx, ecx
.Repeat
Print Str$("\n#%i\t", ecx), Dest$(ecx) ; see dest 0...2, then source 0...9
inc ecx
.Until ecx>=stack
pop eax
Exit
end start
Output:
#0 Destination #0
#1 Destination #1
#2 Destination #2
#3 Source #0
#4 Source #1
...
#12 Source #9
Version 25 April supports ArraySet (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1129) for strings and numerical arrays.
Excerpt from MbSnippets.asc:
include \masm32\MasmBasic\MasmBasic.inc
Init
PrintLine "ArraySet strings:"
ArraySet My$() = "These", "are", "four", "strings"
Let My$(My$(?))="Only strings support" ; My$(?) is the current number
Let My$(My$(?))="dynamic expansion" ; of elements in the array
For_ ecx=0 To My$(?)-1
PrintLine Str$(ecx), Tb$, My$(ecx)
Next
PrintLine CrLf$, "Same with numerical arrays:" ; could be DWORD, REAL4, REAL8
Dim MyNum(5) As DWORD ; create an array with 6 elements (0 .. 5)
ArraySet MyNum() = 11, 22, 33, 44, 55, 66 ; assign values
xor ecx, ecx
.Repeat
Print Str$(MyNum(ecx)), Spc2$
inc ecx
.Until ecx>=MyNum(?)
Exit
end start
Output:
ArraySet strings:
0 These
1 are
2 four
3 strings
4 Only strings support
5 dynamic expansion
Same with numerical arrays:
11 22 33 44 55 66
Version 31 May 2014 (download (http://masm32.com/board/index.php?topic=94.0)) fixes an odd bug: I had built the tinf.lib used for the new UnzipFile function with /subsystem:CONSOLE, so all code using tinf had a console window, including the spreadsheet viewer (http://masm32.com/board/index.php?topic=3231.0).
The new UnzipFile decompresses zipped files to a buffer; more in \Masm32\MasmBasic\MbGuide.rtf
Check also the improved QSort function; it allows now to sort string matrices by column, as demonstrated in the spreadsheet viewer.
Update 5 June (download) - the unzipper is now even simpler to use:
include \masm32\MasmBasic\MasmBasic.inc
Init
UnzipInit "\Masm32\MasmBasic\Res\UnicodeTest.zip"
; now restore the first file, and don't forget the timestamp
FileWrite Files$(0), UnzipFile(0), GfLastWrite(0)
UnzipExit ; cleanup
Exit
end start
It handles Unicode file names, and you can retrieve the optional comment, too.
Full example here (http://masm32.com/board/index.php?topic=3215.msg34107#msg34107).
Tonight's version of MasmBasic had a little bug in the deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) macro:
include \masm32\MasmBasic\MasmBasic.inc
Init
MovVal f:xmm1, "12345678901234567890"
deb 1, "Result", f:xmm1
Exit
end start
You have the latest version with the bugfix if the box displays
Result f:xmm1 1.234567890123457e+19
If you see any other number, download the latest version here. (http://masm32.com/board/index.php?topic=94.0)
For latest additions, see True Unicode (http://masm32.com/board/index.php?topic=3310.0) in the Campus.
Downloaded and installed a version 12 hours ago, all OK.
Saw the new version, downloaded and installed OK until the very end showing RichMasm
Faulting application name: RichMasm.exe, version: 0.0.0.0, time stamp: 0x53a20f44
Faulting module name: RichMasm.exe, version: 0.0.0.0, time stamp: 0x53a20f44
Exception code: 0xc0000005
Fault offset: 0x0000ff0c
Faulting process ID: 0x1940
Faulting application start time: 0x01cf8b99d380e62d
Faulting application path: C:\Masm32\MasmBasic\RichMasm.exe
Faulting module path: C:\Masm32\MasmBasic\RichMasm.exe
Report ID: 130f4421-f78d-11e3-bfda-bc5ff496160b
Faulting package full name:
Faulting package-relative application ID:
Thanks for the feedback, Sinsi. If the offset means "from entry", then it is pcmpeqb xmm0, xmmword ptr [edx] in MbStrLen. So a nullpointer was passed ::)
I always wonder what a len() routine should return if a nullpointer is passed. Zero maybe? Minus one??
Which Windows version was that? Anybody else having the same problem?
The SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) macro allows now to initialise DWORD, WORD, REAL4, REAL8 and string variables in the declaration:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals v1=123456789, MyFile$="SomeTest.txt", v2
SetGlobals MyR4:REAL4=123456.789012345678, MyR8:double=123456.789012345678
SetGlobals v3:WORD=12345, v4
Init
SetGlobals ; no args = load ebx, initialise variables
Print "MyFile$=", MyFile$, CrLf$
Print Str$("V1=%i", v1), Str$(", v3=%i\n", v3)
Print Str$("R4=%If\n", MyR4)
Print Str$("R8=%If\n", MyR8)
Exit
end start
String variables must have the '$' suffix. In the first call of the .code section (i.e. the line below Init), SetGlobals without arguments initialises these variables.
EDIT: Update 3 July fixed a very odd bug: Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172), when reading an ANSI file that had Unicode embedded, had extremely long strings containing the Unicode parts; that may happen if you saved an inc file as Unicode, and afterwards you create e.g. with copy *.inc AllIncludes.txt a file that will have, oops, an embedded Unicode part. The BadLines variable can be used to test this:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Recall "\Masm32\include\AllIncludes.txt", L$()
ExternDef BadLines:DWORD
Print Str$("%i lines, of which ", eax), Str$("%i badly formatted", BadLines)
Exit
end start
In the new version, the array will simply contain Unicode strings where Recall found them; no more obscure crashes, but still, garbage in, garbage out...
Note that Recall has no problems with regular Unicode files - it returns the string array in UTF-8 format (and you can use wRec$(My$(123)) if you need UTF-16, e.g. for menus).
Hi JJ
not sure if you are aware of this small bug on masmbasic, but with winXP SP3, the menus text are being detached when you resize the window.
To see the error, you need to open masmbasic and then press the mouse upon a windows and drag it vertically.
1st - Double click the window to you be able to drag it
2nd one the window is not maximixed, click on the title bar with the left button pressed and drag the window
(http://i62.tinypic.com/e8pjt4.jpg)
Hi Gustavo,
It's a feature, not a bug ;-)
On my machines (Win XP, W7-32, 2*W7-64) it works, though. The menus get detached while dragging or resizing but follow some milliseconds later. Strange that for you it's different.
The background for this strange feature is
a) Aero (not allowing drawing directly on the caption) and
b) the fact that assembly is a "vertical" language, with one short instruction per line: I didn't want to sacrifice a line for a stupid standard menu.
Besides, the menu activates itself without clicking, like most browser menus nowadays.
Still, I am curious why the menu stays put in the middle of the desktop in your case... ::)
A feature ? Hmm..interesting...I never used aero before to see what exactly it is.
But...since this is the normal behavior, son´t worry...the menus on the middle of the desktop goes back to the original position after a few time (milliseconds, in fact)....I took the screenshot pressing "PrintScreen" thinking it was a bug to show you, because i didn´t found other way to explain.
But...do aero works on XP ? I would like to see what is this feature. It is unusual, but, interesting.
No aero on XP. It was introduced with Vista, but it seems not very popular. Most people I know reverted to the classic non-aero themes. Don't even know if it still exists on Win8.
BTW the editor is not needed to assemble MasmBasic code, but it has some nice features. For example, load a big source (>10,000 lines), select a global variable like "buffer" and hit F3...
Just for fun, a 40 lines app to find duplicate files, starting from the current folder:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=CurDir$()+"*.*"
.While 1
Let esi=Input$("\nEscape+Return to quit\nEnter path & wildcards:\t", esi) ; e.g. C:\Masm32\*.*
.Break .if !Len(esi) ; user pressed Escape
.if !Instr_(esi, "*")
PrintLine "Unrestricted search not allowed"
.else
GetFiles esi
.if eax
push eax
Print Str$("%i files found\n\n", eax)
xor ecx, ecx
.Repeat
mov edi, Files$(ecx)
mov ebx, Rinstr(edi, "\") ; let's move the name part to the front for sorting
.if ebx
Let Files$(ecx)=Mid$(edi, ebx+1)+Tb$+GfDate$(ecx)+Spc2$+GfTime$(ecx)+Spc2$+Str$(GfSize(ecx))+Spc2$+Left$(edi, ebx)
.endif
inc ecx
.Until ecx>=stack
SortFiles name, asc ; sort by name, ascending
xor ecx, ecx
Let ebx="#" ; no such file
.Repeat
mov edi, Files$(ecx)
.if Instr_(ebx, Left$(edi, Instr_(edi, Tb$)), 1)==1
PrintLine CrLf$, edi, CrLf$, ebx
.endif
Let ebx=Files$(ecx)
inc ecx
.Until ecx>=stack
pop eax
.endif
.endif
.Endw
Print "bye"
Exit
end start
Jochen,
nice little application. I've no redundancy on my machine. :lol:
Gunther
Quote from: Gunther on August 19, 2014, 05:17:02 AM
nice little application. I've no redundancy on my machine. :lol:
Thanks, Gunther.
Update 20 August (here (//http://)):
- GfSetInfo allows to copy a file's timestamp and size to another element of the Files$() array generated by GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056), or time & size of the last match of Exist(); example:
GfSetInfo 1, GfLastWrite(-1) ; set Files$(1) to Exist() time and sizeDestination is an element of Files$(), source is either Files$ (index 0 ... n) or the last match of Exist (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1049)() with index -1.
- wChr$() can now have embedded zeros:
mov esi, wChr$("All files", 0, "*.*", 0)This allows to avoid a bug in LoadStringW when loading a resource string with trailing zeros. (http://masm32.com/board/index.php?topic=3509.msg36865#msg36865).
- the menus of RichMasm are now better aligned, see Pelles C (http://forum.pellesc.de/index.php?topic=6370.0)
CASE WM_DROPFILES
GetFiles WM_DROPFILES ; put dropped files into the Files$() array
push eax
Let esi=Str$("%i files and folders dropped:", eax)
xor ecx, ecx
.Repeat
void Rinstr(Files$(ecx), "\") ; strip the path: Rinstr() returns absolute pos in eax (and relative pos in edx)
lea edi, [eax+1]
Let esi=esi+Str$("\n%i\t", GfSize(ecx))+GfDate$(ecx)+Spc2$+GfTime$(ecx)+Tb$+edi ; size, date, time and filename
inc ecx
.Until ecx>=stack
pop eax
SetWin$ hEdit=esi
Sample output:
7 files and folders dropped:
0 13.01.2012 19:59:15 procs
0 13.01.2012 19:59:14 tutorial
0 13.01.2012 19:59:14 tools
65536 17.08.2014 15:04:04 uniedit.exe
5598 17.08.2014 04:13:03 AllFiles.zip
22528 17.08.2014 00:40:24 topgun.exe
37376 17.08.2014 00:25:44 qeditor.exe
Full source attached, requires MasmBasic of 25 August 2014 (http://masm32.com/board/index.php?topic=94.0).
Good idea, Jochen. Thanks. :t
Gunther
Version 22 Sept 14 (download (http://masm32.com/board/index.php?topic=94.0)):
- BUGFIX: Val (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1202)("12.34.56") returns now correctly 12.34
- BUGFIX: StringsDiffer (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1157) used wrong location to test the case-insensitive flag
- New feature: Now dialogs (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1012) close apart from IDOK and IDCANCEL also for IDs 100...120, and return the ID
Bugfix 5 October (download (http://masm32.com/board/index.php?topic=94.0)):
For a while, the FileRead$() function had "forgotten" how to read a file from the Internet - sorry :redface:
Now the snippet below works again. It downloads an attachment from this forum, checks the zip directory for the first *.asm file, and displays the first 1.8 k on the screen:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
; assign contents of a well-known file to esi:
Let esi=FileRead$("http://masm32.com/board/index.php?action=dlattach;topic=49.0;attach=30")
FileWrite "tmp.zip", esi, LastFileSize ; write contents to a temporary file
UnzipInit "tmp.zip" ; expects a filename, returns a comment (if present)
.if Sign?
Print eax ; print an error message
.else
For_ ecx=0 To edx-1 ; #files returned in edx
mov esi, Files$(ecx)
.if Instr_(esi, ".asm", 1) ; assembler source, plain text?
PrintLine "## First 1800 chars of ", esi, " ################# : ", CrLf$, Left$(UnzipFile(ecx), 1800), " ..."
.endif
Next
UnzipExit
.endif
Inkey "## Cute, isn't it? #################"
Exit
end start
MasmBasic update of 15 October (download) concerns mainly improvements of the editor:
- plugins don't need to be registered in the menus.ini file, it is sufficient to build them in the plugin folder
- all menus allow now tooltips, as shown below; for plugins, they can be defined in the source using txName db "name in menu§description of\nthe plugin", 0
I know it's hard to believe but YES, MasmBasic had a bug: wLeft$/wRight$/wMid$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1159) didn't work :redface:
The Ascii versions were ok but the wide (Unicode) versions returned drastically shortened strings. No idea when this regression crept in but now it's fixed (http://masm32.com/board/index.php?topic=94.0). Test it e.g. with the "talk to Excel" example in \Masm32\MasmBasic\Res\Masm2ExcelCircle.asc, line 39:
xlsFormat CF_UNICODETEXT ; back to Unicode
wPrint "Cur selection", wTb$, wMid$(xlsRead$(), 16), wCrLf$ ; get current selection, strip the string "Real Unicode":
Note that in order to see the Unicode strings returned by Excel properly, you need to set the console font to Lucida Console (in the console window's system menu, properties, font).
Other good news is that UnzipFile() (see \Masm32\MasmBasic\MbGuide.rtf - based on JibZ' Tiny Inflate Library (http://www.ibsensoftware.com/download.html)) is now twice as fast (the bad news is I had to abandon Pelles C to achieve that :().
Update 10 November: Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) is now thread-safe. This was never a problem in console apps, but GUI apps could occasionally choke. It's fixed.
Other changes:
- Dll (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1017) accepts now environment variables such as %ProgramFiles% - works with non-English Windows versions, ok for Win7-64:
Dll "%ProgramFiles%\FreeArc\Addons\InnoSetup\unarc"
- Err$() allows an optional text, and instead of throwing a runtime error, you can programmatically check the availability of a DLL or certain functions inside a DLL:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
DllRTE=1 ; 1=throw runtime error if LoadLibrary fails (default), 0=no runtime error, check eax instead
Dll "shimgvw" ; load the shell image view dll aka Windows Picture and Fax Viewer Library
DecRTE=0 ; 1=throw runtime error if GetProcAddress fails (default), 0=check eax instead
Declare void ImageView_Fullscreen, 4 ; ImageView_Fullscreen expects 4 dwords but returns nothing useful
.if eax
ImageView_Fullscreen(0, 0, wCL$(1), SW_SHOW) ; we need the wide version of the commandline arg
Err$(0, "ImgView:") ; there is no retval - you may test here for errors
; Err$(0, L) ; same but titled "Error in line xx:"
.else
PrintLine "Problem with procedure: [", Trim$(Err$()),"]" ; use Err$() without args for printing
.endif
Exit
end start
Jochen,
Quote from: jj2007 on November 10, 2014, 12:52:49 PM
Update 10 November: Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) is now thread-safe. This was never a problem in console apps, but GUI apps could occasionally choke. It's fixed.
well done. :t
Gunther
The MasmBasic update of 17 November (download (http://masm32.com/board/index.php?topic=94.0)) features a number of improvements under the hood, in particular an almost fool-proof handling of Unicode filenames. Example:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=wCL$()
.if wExist(esi)
wOpen "I", #1, esi
wLet edi=Input$(#1, Lof(#1))
Close
wMsgBox 0, edi, wCat$("Contents of "+LastFileName$+":"), MB_OK
.else
wMsgBox 0, esi, "No such file:", MB_OK
.endif
Exit
end start
Among other improvements, MasmBasic's preferred editor, \Masm32\MasmBasic\RichMasm.exe, can now build directly with non-Latin alphabets:
include \masm32\MasmBasic\MasmBasic.inc
Init
uMsgBox 0, "Добро пожаловать", "Hi", MB_OK
Exit
end start
Jochen,
your Russian is getting better and better. :t And MasmBasic, too. That's clear.
Gunther
Quote from: Gunther on November 19, 2014, 04:05:05 AMyour Russian is getting better and better. :t And MasmBasic, too. That's clear.
Gunther,
Thanks :P
I use Russian for Unicode demos because the font is installed on most machines (unlike Chinese, for example), but as a matter of fact, I did speak Russian when I was young. Now I've forgotten everything, since I never practised it seriously.
I know the filling, I used to speak German when I was young but when I come to Australia(1992) I was mixing German with English, so I had to push the German somewhere deep in my memory and now it is hard to dig it out :biggrin:
Jochen,
Quote from: jj2007 on November 19, 2014, 05:19:46 AM
I use Russian for Unicode demos because the font is installed on most machines (unlike Chinese, for example), but as a matter of fact, I did speak Russian when I was young. Now I've forgotten everything, since I never practised it seriously.
Интересно, так что вы не говорите по-русски.
Gunther
Update of 6 December:
GfCallback defines a callback function to monitor progress in GetFiles or GetFolders:
include \masm32\MasmBasic\MasmBasic.inc
Init ; <<< select init and hit F6 to test this snippet
Let esi=ExpandEnv$("%WINDIR%") ; usually C:\Windows
PrintLine "Searching ", esi
GfCallback cbGetFiles ; define a callback function
GetFolders esi
Print Str$("\n%i folders found\n", eax)
Exit
cbGetFiles:
test edx, 1023 ; file or folder counter
.if Zero?
Print "*" ; console mode progress bar ;-)
.endif
ret
end start
Minor fixes in MasmBasic version 9 December 2014 (download (http://masm32.com/board/index.php?topic=94.0))
- ToolTips (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1096) don't use edi ebx any more, i.e. you can use them in a loop; keep away from esi, though, and note that ecx will exceptionally be trashed here.
- the GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) GfCallback (examples (http://masm32.com/board/index.php?topic=3838.msg40571#msg40571)) gives access to WIN32_FIND_DATAW in ebx (edx=file counter, edi=last path of FindFirstFileEx)
- Dim (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1126) MyArray() As dword will choke now, and invite you to use uppercase DWORD (or BYTE, REAL8, whatever); note also that Dim without specifying the number of elements, i.e. Dim whatever() As WHATEVERSTRUCT is perfectly legal - same for strings and other types: MasmBasic arrays are dynamic. Just make sure you assign elements incrementally starting with zero, i.e. Let My$(0)="..." or mov MyRect(0, left)=123 etc
- FileRead$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075) occasionally threw generic API errors when the file was not found; now it chokes correctly with "can't find thatfile.txt"
Minor update of 16 December 2014 (download (http://masm32.com/board/index.php?topic=94.0))
One new feature: Extract$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1156) has a new flag called xsScan, which serves to extract substrings sequentially using the same delimiter to the left and right. Example:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="My car,is,red,but, if it ,was, green, I, would,still,drive,it."
.While 1
.Break .if !Extract$(esi, ",", ",", xsScan or xsTrim)
PrintLine "[", eax, "]"
.Endw
Inkey "ok?"
Exit
end start
Output:
[My car]
[is]
[red]
[but]
[if it]
[was]
[green]
[I]
[would]
[still]
[drive]
[it.]
ok?
Interesting feature, Jochen. :t Well done.
Gunther
Update 24.12.2014 (download (http://masm32.com/board/index.php?topic=94.0)):
In addition to the standard file pattern, GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) can now take special arguments:
1. GetFiles <pattern>
GetFiles *.asm ; simple: puts all filenames from the current folder into the Files$() array
GetFiles C:\Windows\System32\msvc*.dll|nt*.dll|nt*.exe
SortFiles ; sort the Files$() array by date, most recent files first
For_ ebx=0 To eax-1 ; print the detailed results
PrintLine Str$(GfSize(ebx)), Tb$, GfDate$(ebx), Spc2$, GfTime$(ebx), Tb$, Files$(ebx)
Next
2. GetFiles CL (or GetFiles wCL for Unicode file names):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
GetFiles CL ; put filenames in the commandline into the Files$() array
For_ ebx=0 To eax-1 ; print the results
PrintLine Str$(GfSize(ebx)), Tb$, GfDate$(ebx), Spc2$, GfTime$(ebx), Tb$, "[", Left$(Files$(ebx), 90), "]"
Next
Inkey Str$("%i files found in commandline", ebx)
Exit
end start
3. GetFiles WM_DROPFILES (in WndProc, main window must have WS_EX_ACCEPTFILES style):
CASE WM_DROPFILES
GetFiles WM_DROPFILES
For_ ebx=0 To eax-1 ; show the files in the edit control
AddWin$ hEdit=Str$(GfSize(ebx))+Tb$+GfDate$(ebx)+Spc2$+GfTime$(ebx)+Tb$+Files$(ebx)+CrLf$
Next
#2 is handy when the user drags a group of files from Explorer over the name of the executable (i.e. the files are passed via the commandline).
#3 does the same but with files dropped over the window itself. During installation, you will see the MasmBasic guide; on top of the page, click on "File" to the left of the usual disclaimers apply, and choose "New Masm source". In the green window, click on Simple window in the upper left corner, hit F6 to build the application, then select files in Explorer and drag them over the application.
The update fixed an issue with a limitation of the line length in ML (all versions), which caused cryptic error messages when the user tried to initialise many global variables. In addition, more types are now possible, also for Swap.
SetGlobals & Swap: C/C++ allows direct assigning of values to variables during their initialisation. Same applies to GfaBasic, code such as
LOCAL my$="Hello", mydouble=123.456 is quite common.
A similar command called SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) has been available for a while, but it choked for multiple assignments. This bug is fixed.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals v1=111, v2=222, a$="String A", b$="String B"
SetGlobals s1:REAL4=111.111, s2:REAL4=222.222
SetGlobals x1:REAL10=111.111, x2:REAL10=222.222
Init
Dim da1() As REAL8 ; create two dynamic double arrays; note the
Dim da2() As REAL8 ; type after Dim ... As it must be uppercase
Print "Arrays:"
For_ ecx=0 To 2
mov esi, Str$("%If", ecx*1.1111111111111111+10)
MovVal da1(ecx), esi ; assign values to arrays - clumsy but OK for testing
mov esi, Str$("%If", ecx*2.2222222222222222+20)
MovVal da2(ecx), esi
Print Str$(" da1(%i)=", ecx), Str$(da1(ecx)), Str$(" da2(%i)=", ecx), Str$(da2(ecx))
Next
deb 4, "original", v1, v2, $a$, $b$, s1, s2, x1, x2, da1(1), da2(2)
Swap v1, v2
Swap a$, b$
Swap s1, s2
Swap x1, x2
Swap da1(), da2()
Print "Arrays:"
For_ ecx=0 To 2
Print Str$(" da1(%i)=", ecx), Str$(da1(ecx)), Str$(" da2(%i)=", ecx), Str$(da2(ecx))
Next
deb 4, "swapped", v1, v2, $a$, $b$, s1, s2, x1, x2, da1(1), da2(2)
Exit
end start
Output:[/tt]
Arrays: da1(0)=10.00000 da2(0)=20.00000 da1(1)=11.11111 da2(1)=22.22222 da1(2)=12.22222 da2(2)=24.44444
original
v1 111
v2 222
$a$ String A
$b$ String B
s1 111.1110
s2 222.2220
x1 111.111000000000000
x2 222.222000000000000
da1(1) 22.22222222222222
da2(2) 24.44444444444444
Arrays: da1(0)=20.00000 da2(0)=10.00000 da1(1)=22.22222 da2(1)=11.11111 da1(2)=24.44444 da2(2)=12.22222
swapped
v1 222
v2 111
$a$ String B
$b$ String A
s1 222.2220
s2 111.1110
x1 222.222000000000000
x2 111.111000000000000
da1(1) 11.11111111111111
da2(2) 12.22222222222222[/tt]
Attached a more detailed example, needs MasmBasic version 26 December (http://masm32.com/board/index.php?topic=94.0).
Version 26.12. choked for Sqrt(2); it's fixed with version 27.12. (download (http://masm32.com/board/index.php?topic=94.0))
Examples for Sqrt():
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals sq:double
Init
movlps xmm0, FP8(2.0) ; load an xmm reg using the Masm32 FP8 macro
Print Str$("sq2=%Jf\n", Sqrt(f:xmm0)) ; it's a float, so put the f: prefix before the xmm reg
mov eax, 3
movd xmm0, eax ; put a value into an xmm reg
Print Str$("sq3=%Jf\n", Sqrt(xmm0)) ; it's integer
fld Sqrt(4)
fstp sq ; sq = sqrt(3), the manual way
Print Str$("sq4=%Jf\n", sq)
Print Str$("sq5=%Jf\n", Sqrt(5, sq))
void Sqrt(6, ST(0))
Print Str$("sq6=%Jf\n", ST(0))
fstp st ; when leaving values on the FPU, do the cleanup!!
Inkey Str$("sq7=%Jf\n", Sqrt(7, ST(0)))
fstp st ; cleanup
Exit
end start
Output:
sq2=1.414213562373095049
sq3=1.732050807568877293
sq4=2.000000000000000000
sq5=2.236067977499789805
sq6=2.449489742783178098
sq7=2.645751311064590590
Jochen,
the cleanup of the FPU stack is always necessary. That has to do with the stack roll over.
Gunther
Quote from: Gunther on December 27, 2014, 01:14:45 PMthe cleanup of the FPU stack is always necessary.
That is
rarely necessary. In fact, the cleanup instruction
fstp st appears only 14 times in the MB source.
QuoteThat has to do with the stack roll over.
While I know what you mean when writing "stack roll over", it is not a term used when dealing with the FPU. You can check that in Raymond's excellent tutorial. (http://www.website.masmforum.com/tutorials/fptute/)
Btw if you want to make a little tutorial for the noobs, you should do it properly: Open a FPU thread in the Campus.
Quote from: jj2007 on December 27, 2014, 06:34:40 PM
That is rarely necessary. In fact, the cleanup instruction fstp st appears only 14 times in the MB source.
I think it's a good style to give back the entire processor in the same state how did you get it. That reduces furthermore error sources. But it's only my point of view, no offense.
Gunther
Update 29 December: (http://masm32.com/board/index.php?topic=94.0) Str$() can now print REAL10 numbers with up to 19 digits precision, if a) the format string contains %Jf and b) the number starts with less than 923... (which is the case for 92.3% of all numbers ;)).
deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) uses this format for all REAL10 variables.
include \masm32\MasmBasic\MasmBasic.inc
.data
qwjj QWORD 7fffffffffffffffh ; aka +9223372036854775807
qwj2 qword -9223372036854775807
SetGlobals numericvar1:REAL10=1.8888888888888888888888888888e9
SetGlobals numericvar2:REAL10=9.2222222222234567895e9
SetGlobals numericvar3:REAL10=9.2333333333333333335e9
SetGlobals numericvar4:REAL10=1.2345678901234567890e9
SetGlobals numericvar5:REAL10=9.2345678901234567890e9
Init
fldpi
deb 4, "Values", numericvar1, numericvar2, numericvar3, PI, ST(0)
fstp st
mov f2sOlly, 123
Print Str$("qword limit\t+%i\n", qwjj) ; 4294967295 or 2147483647
Print Str$("qword limit\t%i\n", qwj2) ; 4294967295 or 2147483647
fldpi
Print Str$("PI=\t\t%Jf\n", ST(0))
fstp st
Print Str$("PI=\t\t%Jf\n", PI)
Print Str$("numericvar1=\t%Jf\n", numericvar1)
Print Str$("numericvar2=\t%Jf\n", numericvar2)
Print Str$("numericvar3=\t%Jf\n\n", numericvar3)
Print Str$("numericvar4=\t%Jf (number starts with 123, 19 digits)\n", numericvar4)
Print Str$("numericvar5=\t%Jf (number starts with 923, 18 digits)\n", numericvar5)
Exit
end start
Output:
Values
numericvar1 1888888888.888888889
numericvar2 9222222222.223456788
numericvar3 9233333333.33333333
PI 3.141592653589793238
ST(0) 3.141592653589793238
qword limit +9223372036854775807
qword limit -9223372036854775807
PI= 3.141592653589793238
PI= 3.141592653589793238
numericvar1= 1888888888.888888889
numericvar2= 9222222222.223456788
numericvar3= 9233333333.33333333
numericvar4= 1234567890.123456789 (number starts with 123, 19 digits)
numericvar5= 9234567890.12345678 (number starts with 923, 18 digits)
Version 2 January (download (http://masm32.com/board/index.php?topic=94.0)): The restriction to not assign eax to an array element is removed. This is now legal code:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim My$()
invoke GetCommandLine ; CL$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1011) is easier to use, but for this demo we take the API
Let My$(1)=eax ; you can now assign eax to an array element
Inkey "Commandline=[", My$(1), "]"
Exit
end start
OPT_Arg1 Hello Forum ; RichMasm's way to supply arguments for testing
Output: Commandline=[C:\somepath\some.exe Hello Forum]
see updated post below
By default, REAL10 numbers are now printed with 19 digits precision. The last digit might be one too high or too low.
The range of printable numbers is now 1.0e+-309, i.e. roughly the range of ordinary doubles.
Speedwise Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186) has improved, it is now about a factor 15 faster than the gcc ssprintf() function provided here by adeyblue (http://masm32.com/board/index.php?topic=3915.msg41398#msg41398) (thanks!!). Attached a testbed using Str$(), MovVal and the gcc counterparts ssprintf() and sscanf().
include \masm32\MasmBasic\MasmBasic.inc ; download version 26 January 2015 (http://masm32.com/board/index.php?topic=94.0)
SetGlobals MyR10:REAL10, Add01:REAL10=0.111111111111111111111
Init
xor ecx, ecx
Print "digits", Tb$, " 1234567890123456789"
.Repeat
inc ecx
push ecx
fld Add01
fimul stack ; load ct*0.111
pop eax
fstp MyR10 ; store back to memory
.if ecx<10 || ecx>=84 && ecx<99 || ecx>=994
Print Str$("\n#%i\t", ecx), Str$(MyR10)
.elseif ecx==10 || ecx==99
Print ; insert a blank line
.endif
.Until ecx>=1000
Exit
end start
Output:
digits 1234567890123456789
#1 0.1111111111111111111
#2 0.2222222222222222222
#3 0.3333333333333333333
#4 0.4444444444444444444
#5 0.5555555555555555555
#6 0.6666666666666666666
#7 0.7777777777777777777
#8 0.8888888888888888888
#9 1.000000000000000000
#84 9.333333333333333333
#85 9.444444444444444444
#86 9.555555555555555555
#87 9.666666666666666666
#88 9.777777777777777777
#89 9.888888888888888888
#90 10.00000000000000000
#91 10.11111111111111111
#92 10.22222222222222222
#93 10.33333333333333333
#94 10.44444444444444444
#95 10.55555555555555555
#96 10.66666666666666667
#97 10.77777777777777778
#98 10.88888888888888889
#994 110.4444444444444444
#995 110.5555555555555555
#996 110.6666666666666667
#997 110.7777777777777778
#998 110.8888888888888889
#999 111.0000000000000000
#1000 111.1111111111111111
Update 2 February 2015 - download here (http://masm32.com/board/index.php?topic=94.0):
1. Join$() converts a string array to one string:
include \masm32\MasmBasic\MasmBasic.inc
Init
Dim My$()
Let My$(0)="Masm32"
Let My$(1)="is"
Let My$(2)="great"
PrintLine "[", Join$(My$()), "]" ; with no second arg, output is [Masm32\nis\ngreat], i.e. items separated by 13, 10
Print "[", Join$(My$(), " "), "]" ; shows [Masm32 is great] with " " as second arg
Exit
EndOfCode
For Split$() and Filter$(), see the guide during installation.
2. Bugfix for Extract$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1156):
When using the flag xsLineR, one byte from the right match string was duplicated. It's fixed. Usage example (this extracts structures from a C header file; you need Visual Studio installed):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
My$ equ esi ; two equates saying we'll use a register for the string to be searched
Struct$ equ edi ; and for the strings returned, in this case C/C++ structures
SetReg64 ; the registry wants to cheat 32-bit programs, we cheat back ;-)
Let My$=GetRegVal("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\2E22551E7BF434E44AAD692811011B7C", "66FC8F6438BA7A83992B5AEB05E74E27", "NoSuchFile.bla")
.if Exist(My$) ; should be something like C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\srv.h
Let My$=FileRead$(My$)
Open "O", #1, "Structures.txt" ; open a file for output
xor ebx, ebx ; reset counter
.While 1
; flags: full word, include beginning of first line and end of last line, use in a loop; 100 lines max (enough for a big structure)
mov Struct$, Extract$(My$, "struct", '}', xsFullW or xsLineL or xsLineR or xsIncR or xsLoop, 100)
.Break .if !Struct$
Print Struct$, CrLf$, CrLf$ ; print to console
Print #1, Struct$, CrLf$, CrLf$ ; and to file
inc ebx
.Endw
Close #1
Print Str$("%i structures found\n", ebx)
.endif
Exit
end start
Output:
typedef struct srv_datetime
{ // Format for SRVDATETIME
long dtdays; // number of days since 1/1/1900
unsigned long dttime; // number 300th second since mid
} DBDATETIME;
typedef struct srv_money
{ // Format for SRVMONEY
long mnyhigh;
unsigned long mnylow;
} DBMONEY;
typedef struct dbdatetime4
{ // Format for SRVDATETIM4
unsigned short numdays; // number of days since 1/1/1900
unsigned short nummins; // number of minutes sicne midnight
} DBDATETIM4;
typedef struct dbnumeric
{ // Format for SRVNUMERIC,SRVNUMERICN,SRVDECIMAL,SRVDECIMALN
BYTE precision;
BYTE scale;
BYTE sign;
BYTE val[MAXNUMERICLEN];
} DBNUMERIC;
4 structures found
As noted on other occasions (http://masm32.com/board/index.php?topic=2630.0), the 64-bit versions of Windows have the bad habit to destroy registers xmm0 ... xmm5 in API calls, nota bene: in 32-bit code on a 64-bit OS. Since 32-bit code on 32-bit Windows does not trash them, and many people may have relied on this benign but undocumented behaviour, there is a nice potential for bugs that come out of the blue when running the same application the first time on a 64-bit OS.
For performance reasons, MasmBasic does not preserve the xmm regs for each and every API call used, but its own algos do preserve the xmm regs.
This worked fine in general, but I ran into a strange case that needed fixing:
include \masm32\MasmBasic\MasmBasic.inc ; download the fixed version of 6 February 2015 (http://masm32.com/board/index.php?topic=94.0)
Init
Dim MyDouble() As REAL8 ; same for QWORD
MovVal f:xmm0, "1234.5678" ; fill low quad of xmm0 with float
movlps MyDouble(0), xmm0
deb 4, "Element 0", f:xmm0, MyDouble(0)
MovVal f:xmm0, "1234.5678"
movlps MyDouble(1), xmm0 ; <<<<<<< this instruction misbehaved
deb 4, "Element 1", f:xmm0, MyDouble(1)
MovVal f:xmm0, "1234.5678"
movlps MyDouble(2), xmm0
deb 4, "Element 2", f:xmm0, MyDouble(2)
Exit
end start
Old buggy version:
Element 0
f:xmm0 1234.567800000000
MyDouble(0) 1234.567800000000
Element 1
f:xmm0 0
MyDouble(1) 0.0
Element 2
f:xmm0 1234.567800000000
MyDouble(2) 1234.567800000000
The reason for this unexpected behaviour was that the simple instruction movlps MyDouble(1), xmm0 has a nice feature under the hood: MyDouble() is a dynamic array. When an index hits the boundary, new memory is being requested via HeapReAlloc. And that request trashed the xmm regs - all six of them. I'd like to trash Windows, but Linux doesn't seem any better, so the solution was to preserve the six regs around the HeapReAlloc call. It works correctly from version 6 Feb 2015 onwards.
Update 10 Feb (download (http://masm32.com/board/index.php?topic=94.0)): Since I ran often into problems with Windows' bad habit to trash xmm0 ... xmm5 in its 64-bit versions, I decided to address this Microsoft 'feature' more systematically.
Inter alia, ordinary message boxes and setting the timestamp for a FileWrite (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1078) did not work in 32-bit code on Win64. This is now fixed, and the simple unzipper below will work as expected:
include \masm32\MasmBasic\MasmBasic.inc
Init
Let esi=CL$()
.if !Instr_(esi, ".zip", 1)
MsgBox 0, esi, "Not a zip archive?", MB_OK
Exit
.endif
UnzipInit esi ; expects a filename, returns a comment (if present); edx returns #records
.if Sign?
Print eax ; print an error message
.else
For_ ecx=0 To edx-1 ; #files returned in edx
Let esi=Files$(ecx)
.if Rinstr(esi, "/") ; zipfiles use forward slashes
xchg eax, esi ; we don't display the full path, and we
inc esi ; don't use folder names for extraction!!
.endif
PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, esi
Inkey "Extract? (yes/no/quit) ", Cr$
.Break .if eax=="q" || eax==VK_ESCAPE
.if eax=="y"
FileWrite esi, UnzipFile(ecx), GfLastWrite(ecx) ; setting the timestamp works now on Win7-64, too
.endif
Next
UnzipExit
.endif
Exit
end start
Update 16 Feb 2015 (download (http://masm32.com/board/index.php?topic=94.0)):
- MovVal MyFloat(ct), My$(ct) is legal code now
- For_ ... Next has Step now (can be negative, too)
- In addition to At(col, row), Print can now take a CColor(foreground, background) arg
include \masm32\MasmBasic\MasmBasic.inc
Init
Dim My$()
Dim MyFloat() As REAL8
For_ ct=0 To 1000
Let My$(ct)=Str$(ct)
MovVal MyFloat(ct), My$(ct)
Next
For_ ct=100 To 1000 Step 100
mov ecx, ct
and ecx, 15
Print At(35, Locate(y)+2) CColor(ecx, cWhite) Str$(ct), Str$("\tMyFloat(ct) = %Jf", MyFloat(ct))
Next
Exit
end start
Update 24 February (download (http://masm32.com/board/index.php?topic=94.0)):
This snippet creates a windows application with a menu and monitors all WM_xx messages to the console.
GuiParas equ "Hello jj2007", x650, y20, w200, h200, cblack, b00FFFFD0h
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
Event Message
inc msgCount
deb 4, "msg", chg:msgCount ; , wParam, lParam ; see deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019)
GuiEnd
More a proof of concept than a serious exercise, but it works. Attached a more detailed example, using create, key, menu and paint "events".
Just for fun:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals fct:REAL10, fStart:REAL8=2.0, fEnd:REAL8=1.5
Init
For_ fct=1.0 To 2.0 Step 0.25
Print Str$("\n%Jf\t", fct)
Next
Print CrLf$, "..."
For_ fct=fStart To fEnd Step -0.1
Print Str$("\n%Jf\t", fct)
Next
Exit
end start
Output:
1.000000000000000000
1.250000000000000000
1.500000000000000000
1.750000000000000000
2.000000000000000000
...
2.000000000000000000
1.900000000000000000
1.800000000000000000
1.700000000000000000
1.600000000000000000
1.500000000000000000
Do u realize the last 12 posts in this thread are yours? Figured I'd break your streak :)
But also it's interesting you're using float instead of integer in the for-next loop, because I've just done the similar thing with timing macros. I'll soon post a "faster" 32-bit algo in the laboratory - this time using MichaelW's timers, everything "by the book", but with "massively parallel" use of xmm registers. I'd gotten used to returning 64-bits from the rdtsc call and couldn't stand being confined to 32-bits again (1 second vs. 100 years) so wrote a 32-bit version of timers using REAL8 to hold the rdtsc result. Works fine, it's fast enough, this way you can add, average print out etc the timing figures easily.
Anyway, c u later!
Thanks for the heads up ;-)
I posted a float example because that's new - integers always worked.
Re rdtsc, printing a qword is not a big deal:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
rdtsc
Print Str$("TSC=%i\n", edx::eax)
invoke Sleep, 1
rdtsc
Print Str$("TSC=%i\n", edx::eax)
Exit
end start
The problems with rdtsc are elsewhere. M$ suggests QueryPerformanceCounter instead, which is under the hood of NanoTimer() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1171).
Sometimes I need a prompt asking for input from a console app. Version 4 March has it:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=NoTag$(FileRead$("http://masm32.com/board/index.php?action=unread;all;start=0"))
Print "[", Prompt$("Type something, please:", esi), "]"
Exit
end start
See Input$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1041) for comparison.
Other changes: For... Next loops with float counters act now, like their integer equivalents, rejecting if start>end.
P.S.: Version 9 March fixes a minor issue with UnzipFile (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1234).
Version 16 March 2015 has improvements under the hood. Inter alia, Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) can now read files directly from the Internet, including csv and tab-delimited files. Unix format (i.e. LF only) will automatically be recognised, Unicode files are translated to UTF-8 text arrays.
Attached a gift for the U.S. members: A 100-lines application that
- reads an archive from the Internet
- extracts a database in csv format
- allows the user to enter:
- either the name of a city, and get its LatLong coordinates
- or LatLong coordinates, and get the nearest three cities
Let me know if it works.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals firstUse, best, second, third, xc:REAL4, yc:REAL4, xNow, xyMin, OneMio:REAL4=1000000.0, zipfile$="ZipCodes.zip", tmp$="~FrLocal.tmp"
Init
.if !Exist(zipfile$)
void FileRead$("http://www.boutell.com/zipcodes/zipcode.zip")
.if Exist(tmp$)
Rename tmp$, zipfile$
inc firstUse ; flag fresh download, show the MsgBox
.endif
.endif
.if Exist(zipfile$)
UnzipInit zipfile$
... -> see attachment
Please install version 17 March of the MasmBasic library (http://masm32.com/board/index.php?topic=94.0).
Older versions have a problem with the translation of *.csv (comma-separated values) into a two-dimensional string array: If the very first column (see Bonaire, Saint below) contained quoted strings with embedded commas, they were interpreted as two columns. This is fixed now, and the snippet below (source and exe attached) will work just fine (as long as WHO provides the database, of course 8))
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Recall "https://extranet.who.int/tme/generateCSV.asp?ds=mdr_estimates", who$(), csv
Print Str$("%i records downloaded", eax)
For_ ct=0 To who$(?)-1
Print CrLf$, who$(ct, 0)
Print At(33, Locate(y)) Spc2$, who$(ct, 4), Space$(40)
For_ ecx=8 To 14 ; columns 8...14 contain the data
Print At(ecx*8-25, Locate(y)) Spc2$, who$(ct, ecx)
Next
Next
Exit
end start
Output:
217 records downloaded
country year e_new_ e_new_ e_new_ e_new_ e_new_ e_new_ source_mdr_ret
Afghanistan 2013 3.7 2.5 4.9 820 560 1100 Model
Albania 2013 0.58 0.02 3.2 2 0 10 Surveillance
...
Bonaire, Saint Eustatius and Saba 2013 2.2 1.3 3.1 0 0 0 Surveillance
Bosnia and Herzegovina 2013 0 0 0.57 0 0 6 Surveillance
Botswana 2013 2.5 1.5 3.5 120 70 160 Survey
Brazil 2013 1.4 1 1.8 840 600 1100 Survey
P.S.: Just stumbled over a public database on crime records. Interesting, but guess what? The database is neither Windows nor Linux, apparently it's MAC - carriage returns only! So I felt morally obliged to add the Mac format to Recall's autodetect feature. That cost a whopping 40 bytes or so extra but it works like a charm. Go to http://masm32.com/board/index.php?topic=94.0 and re-install MasmBasic, so that you can test the snippet below :biggrin:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Recall "http://samplecsvs.s3.amazonaws.com/SacramentocrimeJanuary2006.csv", Crime$(), csv
For_ ct=0 To Crime$(?)-1
.if Instr_(Crime$(ct), "card info", 1) || ct==0
xor esi, esi
For_ ecx=0 To 8
Print At(esi, Locate(y)) Spc2$, Crime$(ct, ecx), Space$(8)
add esi, 8
.if ecx==1 || ecx==5
add esi, 18
.if ecx==5
add esi, 10
.endif
.endif
Next
Print
.endif
Next
Print Str$("\n%i records received from Sacramento", Crime$(?))
Exit
end start
Jochen,
I figured it was about time I gave masmbasic a try but I am unable to install.
I double click on the exe and I get a window with a title:
"Last chance - show me where macro.asm sits and then a messagebox that says I should google Visual Basic??
James
James,
Sorry for that. To deter the script kiddies, the installer tests if you have Masm32 installed, via the registry. If it doesn't find exactly what it expects, it gives you a "last chance" to select the macros.asm file in your Masm32 installation. It sits in the dedicated Masm32 folder. Please let me know if it works; I am also curious why it doesn't find the registry entries.
Thanks,
Jochen
i might be wrong, but i think the masm32 install only writes to the registry if the user elects to use QE as the default ASM editor
You might be right, Dave :biggrin:
It is now available.
James
Great :t
GuiParas equ "Hello James", x650, y20, w200, h200, sWS_CAPTION OR WS_POPUPWINDOW, cblack, b00FFFFD0h
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
Event Message
inc msgCount
deb 4, "msg", chg:msgCount ; , wParam, lParam ; see deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019)
GuiEnd
Update 24 March 2015:
- gsl (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1123) interface improved (see original gsl example program (http://www.gnu.org/software/gsl/manual/gsl-ref.html#An-Example-Program)):
include \masm32\MasmBasic\MasmBasic.inc
gsl double gsl_sf_bessel_J0 (double x) ; double x means a REAL8 is required as input
Init ; ## GNU Scientific Library: Bessel function ##
Print Str$("Bessel(5)=%Jf \n", gsl_sf_bessel_J0(FP8(5.0)))
fstp st ; see a detailed gsl example here (http://masm32.com/n%5Cmasm32%5CMasmBasic%5CRes%5CSkelGsl.asc)
Exit
EndOfCode
- SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) understands C-style declarations:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals OWORD xx0, xx1, xx2, xx3, xx4, xx5, xx6, xx7
Init
mov eax, 11111111
movd xmm0, eax
movaps xx0, xmm0
add eax, 11111111
movd xmm1, eax
movaps xx1, xmm1
Exit
end start
Update 3 April 15 (http://masm32.com/board/index.php?topic=94.0): How to steal goodies from other languages... before distributing or selling any of this, study the copyright situation 8)
include \masm32\MasmBasic\MasmBasic.inc
; libgsl.dll download (http://gnuwin32.sourceforge.net/packages/gsl.htm) : open Binaries zip, and extract the two files libgsl.dll and libgslcblas.dll to \masm32\MasmBasic\GnuScLib\DLL
gsl double gsl_sf_sin (double x) ; define your required gsl function using the syntax of the GNU Scientific Library Reference (http://www.gnu.org/software/gsl/manual/gsl-ref.html)
SetGlobals threezero:double=3.0
Init
Dll "python34" ; needs Python 3.4.3 (direct link to MSI (https://www.python.org/ftp/python/3.4.3/python-3.4.3.msi))
Declare void Py_Initialize, C:0
Declare void PyRun_SimpleString, C:1 ; can be used like the commandline version of Python
Declare void Py_Finalize, C:0
Py_Initialize()
PyRun_SimpleString("print('Printing the sinus of 3.0 in various languages:')") ; use Python in MasmBasic
PyRun_SimpleString("import math") ; the math library needs to be imported first
PyRun_SimpleString('print("Sinus(3)=", math.sin(3), " Python 3.4.3")')
Print Str$("Sinus(3)= %Jf\tGSL, global var\n", gsl_sf_sin(threezero))
fstp st ; since doubles are returned via the FPU, ST(0) must be popped
Print Str$("Sinus(3)= %Jf\tGSL, immediate\n", gsl_sf_sin(3.0))
fstp st
Dll "msvcrt" ; good ol' CRT
Declare double sin, C:1
Print Str$("Sinus(3)= %Jf\tCRT, global var\n", sin(threezero))
fstp st
Print Str$("Sinus(3)= %Jf\tCRT, immediate\n", sin(3.0))
fstp st
fld FP10(3.0) ; finally, the traditional way, using the FPU
fsin
Print Str$("Sinus(3)= %Jf\tAssembler/Fpu\n", ST(0))
fstp st
PrintLine "Exact: 0.14112000805986722210074480... Wolfram Alpha" ; link (http://www.wolframalpha.com/input/?i=sin%283%29)
Py_Finalize()
Inkey "--- hit any key ---"
Exit
EndOfCode
Output:
Printing the sinus of 3.0 in various languages:
Sinus(3)= 0.1411200080598672 Python 3.4.3
Sinus(3)= 0.1411200080598672135 GSL, global var
Sinus(3)= 0.1411200080598672135 GSL, immediate
Sinus(3)= 0.1411200080598672135 CRT, global var
Sinus(3)= 0.1411200080598672135 CRT, immediate
Sinus(3)= 0.1411200080598672221 Assembler/Fpu
Exact: 0.14112000805986722210074480... Wolfram Alpha
The only interaction the installer has with the OS apart from disk IO is the VBS script file that gives you the option of putting the editor on the desktop. There is no direct registry writes at all. This is done to ensure the SDK is fully portable.
Thanks, Hutch. So the registry entry that I found for qEditor was probably what I created myself when associating .asm with qEditor.
I have changed the installer accordingly. It checks now for the presence of x:\Masm32; if more than one installation exists, it checks the timestamps of x:\Masm32\Examples\*.exe, and picks the drive that has the more recent executables in the examples folder tree. Only GetDriveType = DRIVE_FIXED are checked.
So, hopefully the latest update of today, 9 April (http://masm32.com/board/index.php?topic=94.0) will work for everybody with a Masm32 installation. Please let me know if it works now.
There are also some improvements under the hood, notably I managed to speed up Len() a little bit:
Comparing Masm32 len() and MasmBasic Len()
Total=401700900 in 31 ms (Len)
Total=401700900 in 217 ms (len)
Total=401700900 in 32 ms (Len)
Total=401700900 in 217 ms (len)
Total=401700900 in 31 ms (Len)
Total=401700900 in 216 ms (len)
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
Testbed attached.
Version 2 - I've added CRT strlen and the "safe" version strnlen:
Comparing MasmBasic Len(), crt_strlen and Masm32 len()
Total bytes:
401700900 in 36 ms Len
401700900 in 229 ms crt strlen
401700900 in 428 ms crt strnlen
401700900 in 259 ms Masm32 len
401700900 in 37 ms Len
401700900 in 229 ms crt strlen
401700900 in 419 ms crt strnlen
401700900 in 261 ms Masm32 len
401700900 in 36 ms Len
401700900 in 227 ms crt strlen
401700900 in 419 ms crt strnlen
401700900 in 263 ms Masm32 len
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
P.S.: Version 10 April (http://masm32.com/board/index.php?topic=94.0) fixed a minor incompatibility with JWasm (the xlsPixels2Points macro used in the DDE demo \masm32\MasmBasic\Res\Masm2Excel.asc assembled fine with ML 6.15 .. 10 but choked with JWasm).
error line (??)
the specified procedure could not be found
xp sp3
Yep, I just verified with my old machine: strnlen is not available on XP... :(
I know feature overkill is a big problem, but I couldn't resist :redface:
Sound
Sound "880:200" ; plays 880Hz for 200 ms; separator can be space, tab, / or :
Sound 111 ; plays a wav resource with ID 111 (rc file: 111 WAVE "hello.wav")
Sound "hello.wav" ; plays a file directly (wav only)
Sound "hello.mp3" ; plays a file in its associated player
Sound "大桥在混乱的水.mp3" ; Unicode names are allowed
Download version 25 April 2015 (http://masm32.com/board/index.php?topic=94.0)
Use the unsafe version, from memory its faster and you just use it correctly.
That is impressive Mr. Jochen :t
Thanks, Onan :icon14:
The MasmBasic update of 23 May concerns basically string arrays with two dimensions, e.g. for use with spreadsheets. Example:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim My$(tab) ; create a two-dimensional string array using tabs (csv: commas) as separators
For_ row=0 To 7
Let My$(row, 0)=Str$("Row %i", row)
For_ col=1 To 7
Let My$(row, col)=Str$("Col %i", col)
Next
Delete My$(row, 6) ; cut out all even columns
Delete My$(row, 4)
Delete My$(row, 2)
Next
For_ row=0 To 7
PrintLine My$(row)
Next
Exit
EndOfCode
Output:
Row 0 Col 1 Col 3 Col 5 Col 7
Row 1 Col 1 Col 3 Col 5 Col 7
Row 2 Col 1 Col 3 Col 5 Col 7
Row 3 Col 1 Col 3 Col 5 Col 7
Row 4 Col 1 Col 3 Col 5 Col 7
Row 5 Col 1 Col 3 Col 5 Col 7
Row 6 Col 1 Col 3 Col 5 Col 7
Row 7 Col 1 Col 3 Col 5 Col 7
EDIT: version 3 May adds the corresponding Insert command:
Dim some$(tab) : same for some$(csv)
Let some$(0)=cfm$("rc00\trc01\trc02\trc03\trc04\trc05\trc06")
Let some$(1)=cfm$("rc10\trc11\trc12\trc13\trc14\trc15\trc16")
Insert some$(0, 3)
Let some$(0, 3)="NEW r0c3"
MasmBasic version 5 May 2015 (http://masm32.com/board/index.php?topic=94.0) fixes two bugs:
- Csv2Tab (converts an array loaded from a *.csv file to tab-delimited) had problems with malformed files;
- mov esi, some$(row, column) could produce garbage in loops with many thousand iterations (Let (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1132)esi= was not affected; mov must be used only for read-only pointers).
Some new functions for the simplified GUI have been added:
output:
(http://www.webalice.it/jj2006/pics/GuiDemo.png)
source:
GuiParas equ "Hello jj2007", x100, y100, w300, h180, b0F0F0A0h
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
MakeFont hFontSmall, Height:15, Weight:FW_SEMIBOLD, "Arial"
MakeFont hFontBig, Height:36, "Script MT Bold"
MakeBrush hRed, RgbCol(255, 64, 64) ; light red
MakeBrush hGB, RgbCol(0, 160, 64) ; dark green
Event Menu
MsgBox 0, Str$("You clicked menu #%i", MenuID), "Hi", MB_OK
Event Paint
m2m ecx, 3 ; just to demonstrate how to use scaling
GuiTextStyle font:hFontSmall, bcol=RgbCol(255, 255, 160), fcol RgbCol(0, 0, 255)
GuiLine 70, 15, ecx*90+10, ecx*5 ; start x+y, end x+y
GuiLine 280, 120 ; end x+y
GuiLine 70, 120
GuiLine 70, 15
GuiSetFill hRed ; use the red brush
GuiEllipse 236, ecx*7+4, 40, 20 ; x, y, radius x, radius y
GuiSetFill hGB
GuiCircle ecx*80-4, 25, ecx*5 ; x, y, radius
For_ ct=0 To 7
GuiText 4, ct*15+4, Str$("Line %i ", ct+1)
Next
GuiTextBox "Добро пожаловать", ecx*4+75, ecx*2+20, ecx*4+250, ecx*2+120, font:hFontBig, bcol:0f0f0a0h, fcol:RgbCol(0, 255, 0)
GuiEnd
This one needs MasmBasic version 19 May 2015 (http://masm32.com/board/index.php?topic=94.0) (works with Unicode tooltips, too):
GuiParas equ "Editor demo", x40, y40, w900, h666
GuiMenu equ @File, &New, &Open, &Save as
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyEdit, "richedit", y=0+37, h=1000-35, text "No valid commandline found"
GuiControl MyTb, "Toolbar", resid 111
SetGlobals MyEd$="Simple editor:", CurrentFile$
SetGlobals
Let CurrentFile$=CL$() ; OPT_Arg1 SimpleEditor.asc ; RichMasm: specify a commandline for testing
.if Len(CurrentFile$)>1
SetWin$(hMyEdit)=FileRead$(CurrentFile$))
.endif
Event Menu
Switch MenuID
Case TB0, 0 ; first toolbar button or first menu entry
MsgBox 0, "New doc?", MyEd$, MB_OKCANCEL
.if eax==IDOK
SetWin$ hMyEdit=Chr$(0)
.endif
Case 1, TB0+1 ; 2nd toolbar button or 2ndmenu entry
.if FileOpen$("Standard Basic=*.bas|Oxygen=*.o2bas|SdlBasic=*.sdlbas|MasmBasic=*.asc", "Open source:")
SetWin$ hMyEdit=FileRead$(FileOpen$())
.endif
Case 2, TB0+2
.if Alert("WARNING: long files will\nbe truncated at 160kBytes", MyEd$, MB_OKCANCEL)==IDOK
.if FileSave$("Standard Basic=*.bas|Oxygen=*.o2bas|SdlBasic=*.sdlbas")
FileWrite FileSave$(), Win$(hMyEdit)
.endif
.endif
Case 3, TB0+3
FileOpenSetFolder FolderOpen$("Pick a folder:", MyEd$, "\Masm32\Examples")
Endsw
GuiEnd
Rsrc
32512 ICON "\\masm32\\MasmBasic\\icons\\Disc.ico" ; Asm, House, Keys, Globe, Hammer, Setup, Disc, Eye, ...
1 24 "\\Masm32\\MasmBasic\\Res\\XpSimple.xml"
111 10 \Masm32\MasmBasic\Res\Tb4Res\SimpleToolbar.zip
Rsrc
glad to see you got it going :t
Well, kind of: with a stripped down manifest. It looks ok, it behaves ok - see attached exe (and source). But it doesn't use the latest version of the common controls...
Just for fun - needs MasmBasic version 20 May 2015 (http://masm32.com/board/index.php?topic=94.0):
(http://www.webalice.it/jj2006/pics/MultiLingualEditor.png)
Source (28 lines of code :icon_mrgreen:) included in the package: when the help file pops up, click on "Try a GUI app" in line 15.
What I always missed with M$ Office (and Windows in general) was an option to switch the language of the user interface. Here is one way to do it: Instead of writing ...
invoke AppendMenu, esi, MF_POPUP, edi, chr$("&File")
... you use ...
invoke AppendMenu, esi, MF_POPUP, edi, Mlg$(File)
... and depending on the language chosen by the user, the menu appears as File or Fichier or Datei.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Mlg$(File:"\Masm32\MasmBasic\Res\Tb4Res\Sample.tab") ; file:"path" loads the multilingual matrix
For_ ct=0 To 5
Mlg$(Language: Mid$("ENESBRITDEFR", ct*2+1, 2)) ; example: Mlg$(Lang:IT) sets Italian
PrintLine Mlg$(LgTx), ":", CrLf$, Tb$, Mlg$(_ASM), CrLf$, Tb$, Mlg$("_BEL")
PrintLine Tb$, Mlg$("_USA"), CrLf$, Tb$, Mlg$(_AUS), CrLf$, Tb$, Mlg$(_AUT)
Next
Exit
EndOfCode
Output (shortened):
English:
American Samoa
Belgium
United States
Australia
Austria
Español:
Samoa americana
Bélgica
Estados Unidos
Australia
Austria
Format of the tab file:
Line 0 = comment, Tb$, ID1, Tb$, Id2, ...
Line 1...n: 3 or 4 letter ID (here: understroke+ISO 3 letter code), Tb$, text, Tb$, text, Tb$, etc.
Do not change this line EN ES BR IT DE FR
LgTxt English Español Português (BR) Italiano Deutsch Français
_ASM American Samoa Samoa americana Samoa Americana Samoa Americane Amerikanisch-Samoa Samoa Américaines
_AUS Australia Australia Austrália Australien Australie
_AUT Austria Austria Áustria Österreich Autriche
_BEL Belgium Bélgica Bélgica Belgio Belgien Belgique
_FRA France Francia França Francia Frankreich
_USA United States Estados Unidos Estados Unidos Stati Uniti d'America Vereinigte Staaten von Amerika Etats-Unis
Example attached, requires MasmBasic of 23 May 2015 (http://masm32.com/board/index.php?topic=94.0)
Source (ca. 70 lines) is in \Masm32\MasmBasic\Res\MiniGui.asc (MasmBasic of 29 May) (http://masm32.com/board/index.php?topic=94.0)
Since I finally have a machine with Windows 8.1 installed, I managed to fix a bug in RichMasm. As of version 11 June 15 (download (http://masm32.com/board/index.php?topic=94.0)), MasmBasic's IDE is fit for Win 8 :t
Note that before installing MasmBasic, you need a valid Masm32 installation. One known issue with Win 8.1 is that you will see these messages several times:
- inc2l.exe: can't find ordinal 200 in windir\AppPatch\AcGenral.dll
- inc2l.exe: can't find ordinal 202 in windir\AppPatch\AcLayers.dll
Masm32 will work just fine, in spite of these error messages.
Note also that Win 8 will display a message "PC protected by Windows" saying that "SmartScreen" has stopped the launch of an unknown application. This is a nasty trick to force coders to buy signatures. Click on "more info" and "Run anyway".
you wanna tell us about the bug ? :biggrin:
Quote from: dedndave on June 11, 2015, 08:33:29 AM
you wanna tell us about the bug ? :biggrin:
It's actually quite weird. There was an access violation in RichMasm, due to a fairly fat
bug - sh*t happens. Windows 7-64 has the strange habit to "fix" such problems somehow, so I never noticed (and I should check why I didn't see it on the XP machine). Win 8 made it crash.
First, I thought it had to do with SEH, but the example in \Masm32\MasmBasic\Res\SkelTryCatch.asc works just fine both in Win 8.1 and in Win 7, so I really don't know why the exception made it crash in Win 8.1 ::)
Another problem was RichMasm's habit to be stingy, pardon: parsimonious with the screen real estate: It uses the caption for the menu titles. That works fine from XP to Win7, but Win 8.1 re-introduced a design feature that will certainly be loved by the fans of Windows 3.1: the captions are centered. So to avoid overlap of menus and title, I had to cheat the OS by padding the caption with spaces to the right. To avoid doing that in Win 7, too, I had to get the OS version. I really wonder when they will retire the person who is responsible for the GetVersion mess, it's incredible. Google for GetVersionEx deprecated manifest, and you'll even find postings that make fun of M$. Richmond, still sleeping...?
what i was looking for was code to avoid
i (we) write code, testing under XP
it would be nice if we could learn the pitfalls to avoid to allow the code to run under win8+
Quote from: dedndave on June 12, 2015, 01:23:15 AM
what i was looking for was code to avoid
So far, the only oddity when passing from Win7-64 to Win 8.1-64 was the access violation in RichMasm, which was swallowed by the OS in Win7. So it seems it's always a good idea to test release code with Olly, because the latter catches the access violations.
A bigger problem was the nasty discovery that the 64-bit OS versions trash xmm regs in 32-bit code, while the 32-bit OS versions leave them intact. In MasmBasic, I eventually solved that with
fxsave MbXs
...
fxrstor MbXs
pairs. The impact on performance is negligible because it concerns only Win API calls.
MasmBasic update of 29 August 2015: (http://masm32.com/board/index.php?topic=94.0)
Switch_, Case_, Default_, Endsw_
The Masm32 Switch macro is more powerful than its C or GfaBasic equivalents, since it can handle even variables or registers in the "cases". Old versions of the MasmBasic Switch_ (note the understroke) could not handle variables, i.e. the cases can be integer constants only. However, under the hood it creates a jump table that is for long lists of cases much faster than the Masm32 macro. Below an example for MasmBasic Switch_:
include \masm32\MasmBasic\MasmBasic.inc
Init ; ## Switch with jump table ##
m2m ecx, -5
PrintLine "------- testing the new MasmBasic Switch_ macro -------"
.Repeat
Print Str$(ecx), Tb$
Switch_ ecx
Case_ -2
PrintLine "Case -2"
Case_ 0
PrintLine "Case NULL"
Case_ 10
PrintLine "Case 10"
Case_ 18
PrintLine "Case 18"
Case_ 14 .. 16
PrintLine "Case 14 .. 16"
Default_
PrintLine "---"
Endsw_
inc ecx
.Until signed ecx>20
Exit
EndOfCode
Rem Switch_ trashes edx but not eax; do not forget the understroke
For the fans of "real" BASIC, I have added Data and Read statements to MasmBasic. Example:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Data 123, "Hello World, how are you?", 'single quotes are allowed', My$, sq$, 456
SetGlobals My$, sq$, c1$, c2$, MyByte, MyDword, MyR4:REAL4, MyR8:REAL8, Last$, MyQ:QWORD
Data 789, 111, 1234567890123456789, 1234567890.123456789, 12345.6789, 12345.6789
Init
Data 33333, "Last string item" ; Data statements can go almost everywhere...
Read ecx, My$, sq$, c1$, c2$, eax ; once My$+sq$ are read, c1$ and c2$ can be copied
Read edx
Read esi
Data 1234567890123456789 ; ... but values must be defined before they are read
Read xmm0, f:xmm1, MyR8, MyR4, edi, Last$, MyQ
deb 4, "Read variables:", ecx, eax, $My$, $sq$, $c1$, $c2$, edx, esi, xmm0, f:xmm1, MyR8, MyR4, edi, MyQ, $Last$
Exit
EndOfCode
Output:
Read variables:
ecx 123
eax 456
$My$ Hello World, how are you?
$sq$ single quotes are allowed
$c1$ Hello World, how are you?
$c2$ single quotes are allowed
edx 789
esi 111
xmm0 1234567890123456789
f:xmm1 1234567890.123457
MyR8 12345.67890000000
MyR4 12345.68
edi 33333
MyQ 1234567890123456789
$Last$ Last string item
QSort (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175) misbehaved - fixed in version 2 September (http://masm32.com/board/index.php?topic=94.0):
qsmb proc
push esi
push esi edi
push ebx 8)
I rewrote the Gui interface a little bit. Of course, it looks horribly BASIC, but traces of pure assembler indicate what is under the hood. And it also offers some eye candy ;D
Oh, and btw - this window is resizable 8)
Assembling requires version 9/11 of MasmBasic (http://masm32.com/board/index.php?topic=94.0).
GuiParas equ "MasmBasic is easy to use", x50, y50, w1200, h666
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
Dim MySinus() As REAL8
For_ ct=-400 To 400
SetFloat MySinus(ct+400)=Sinus(ct) ; ******* a GUI demo in 30 lines of code *******
Next
Event Menu
MsgBox 0, Str$("You clicked into menu entry #%i", MenuID), "Hello:", MB_OK
Event Paint
ArrayPlot hWnd, RgbCol(255, 255, 128) ; init & set background
ArrayPlot MySinus(), 0, lines=5 ; draw the array
ArrayPlot exit, "Playing with Sinus() plots" ; finish with a title
For_ ct=20 To GuiWidth-20 Step 10
GuiLine 50.0, 8.0, ct, 99.0, RgbCol(255, 160, 160) ; the 'pink pyramid'
void Cosinus(ct)
fimul GuiHeight
fiadd GuiHeight ; center
fmul FP4(0.4)
push eax ; create a slot
fistp stack ; convert to integer
pop ecx ; retrieve as ecx
GuiText ct+30, ecx+50, Str$(ct), bcol RgbCol(255, 255, 128)
GuiCircle ct, ecx+60, 1.5, b Rand(0ffffffh), p RgbCol(80, 80, 80)
Next
GuiEllipse 32.0+9, 20.0, 7.0, 8.0, b RgbCol(255, 128, 128) ; RGB for n00bs
GuiEllipse 60.0-9, 20.0, 7.0, 8.0, b 0FF2020h, p 808080h ; BGR for experts
GuiTextBox 50.0-60, 40.0, 120, 100, "This is just a simple text box, try to do the same in other programming languages", bcol RgbCol(255, 255, 255)
GuiCircle 50.0, 40.0+50, 12.0, p 0, b none ; none = hollow brush
EndOfCode
(http://forum.basicprogramming.org/index.php?action=dlattach;topic=3709.0;attach=2707;image)
Somebody complained about RichMasm not being configurable, so in version 18 September (http://masm32.com/board/index.php?topic=94.0) I added the option to change the RichEdit control's background colour.
See ColBg in \Masm32\MasmBasic\Res\RichMasm.ini for a list of available background and foreground colours (you may change the ini file, but the next installation will overwrite your changes, so keep a backup please).
To change the background colour for a document, press Ctrl G and enter e.g. udc=2. Available colours:
ColBg=0FFFFE0h ; default, turquois
Bg1=0F0F0F0h ; almost white
Bg2=0C0FFB0h ; greenish
Bg3=0C0C0FFh ; light red
Bg4=0B0FFFFh ; light yellow
Bg5=0FFB0FFh ; pink
Bg6=202020h ; grey; 1=almost black, 0 picks default colour ColBg
BgH=0AAFFFFh ; reserved for hilite colour
ColFg=0 ; default text colour
Fg8=0B0B0B0h ; light gray
Fg16=0A0h ; dark red
Fg24=0A00000h ; dark blue
Fg32=0aaaah ; dark yellow
Fg40=0ffffffh ; white
Fg48=8000h ; green
udc=14 would pick dark grey background with light gray text colour. While the background changes as soon as you hit Enter, the text colour will change only if you select all text and then hit Ctrl E twice.
Among the templates, "Editor with toolbar" has been improved, and the first on top of the list when clicking menu File/New Masm source called "MessageBox only" looks now a bit different, thanks to a radical redesign of RichMasm:
Hi jj!
A lot better.
I don't remember if was posible to open asm files in RichMasm from the explorer. Now it's no posible.
Regards. HSE
Problem could be an obsolete file association, or that RichMasm.exe and your asm file are on different drives. Try finding ???:\Masm32\MasmBasic\RichMasm.exe, then drag an asm file over the exe.
Version 20 September: (http://masm32.com/board/index.php?topic=94.0) Problem fixed. RichMasm will work now even if the source is on a different drive.
Perfect now :t
Quote from: HSE on September 20, 2015, 11:52:16 AM
Perfect now :t
In this case, I have a special version of the help file for you :greensml:
Better and better! Thanks
But I use a lot of text coloring, for assembly programming mostly in RadAsm (a more dark version that the released one) . Of course some pure GreyAndBoring for small tests in QEditor.
Testing MasmBasic, RichMasm is always the first option :biggrin:.
Version 25 September 2015 (http://masm32.com/board/index.php?topic=94.0) features:
- fast string search:
.if Instr_ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153)(FAST, pBuffer, pPattern, 0)
Print "substring found"
- fast MemSet:
MemSet offset somebuffer, 0, 1000 ; destination, pattern, #bytes
MemSet offset somebuffer, "x", 1000 ; 1000 * x
MemSet offset somebuffer, Mirror$("abcd"), 1000 ; 250 * abcd, slightly faster
mov eax, Chr$("Masm32 is great ") ; string must have (at least) 16 bytes
movups xmm0, oword ptr [eax]
mov edx, offset somestring
MemSet edx, xmm0, 99
The two new commands are on recent CPUs more than twice as fast as their C/C++ equivalents; Instr_() supports also mode 2, i.e. ignore case of the first character (as in "This is OK, this too") without significant speed loss.
Avast don't like that Setup.exe :(
Avast dislikes many things, just disable it temporarily. I have no time and no money to sue them for damaging the reputation of the library, but false positives are a fat problem. Did you know that we have even a dedicated sub-forum called AV Software sh*t list? (http://masm32.com/board/index.php?board=23.0)
Attached an updated "MasmBasic for C" example. Extract to a folder named \Masm32\MasmBasic\Mb4C and make sure it's on the same drive as Masm32 and Pelles C (this is clumsy, I know, and will change when I find time to fix it).
soooo
should i uninstall an older version first, or will the new one take care of it ?
better question here....
how do i do a clean uninstall of MasmBasic?
Quote from: dedndave on September 26, 2015, 03:15:45 AMshould i uninstall an older version first, or will the new one take care of it ?
...
how do i do a clean uninstall of MasmBasic?
The installer will just overwrite any MB files, unless they have been altered after the new version. Normally, you can't do anything wrong with this logic; unless you fumble with MasmBasic.inc, and forget to make a backup. But that would be about as stupid as improving Windows.inc and re-installing Masm32 :biggrin:
Re uninstall: It doesn't write anything to the registry, so it's just the \Masm32\MasmBasic folder. The editor has the habit to save user-written code to \Masm32\MasmBasic\AscUser, so you might check if there is anything valuable in there.
Attached a list of all currently installed files.
thanks Jochen :t
it's been a while since i updated it
so, i will delete the folder and install "anew"
Good idea ;)
I've also just updated the web-based copy of MbGuide.rtf called MasmBasic Quick Reference (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm). Instr_(Fast...) as well as InstrOr(haystack, needle1 or needle2 or needle3) are now documented there. (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153)
Version 1 October 15 features the new ultrafast variant of Instr_():
Instr_, Rinstr, wInstr, InstrOr
Print "The current drive is ", Left$(ThisExe$, Instr_(ThisExe$, "\")-1)
mov pos, Instr_(1, L$(n), "equ", 1+4) ; 1=start pos, 1=case-insensitive + 4=full word
Rem - returns relative pos in edx, absolute in eax
- if no match is found, zero is returned in edx, and eax points to the start of the 'haystack'; same if 'needle' is empty
- six syntax variants allowed:
A: has startpos: Instr_(1, "Test", "Te", 2) ; 4 args
B: no startpos: Instr_("Test", "Te", 2) ; 3 args, last one immediate = mode
C: has startpos: Instr_(1, "Test", "Te") ; 3 args, last one not immediate
D: no startpos: Instr_("Test", "Te") ; 2 args
E: test several patterns: InstrOr("Test", "Te" or "st", 1) ; 3 args (startpos is 1)
F: extra fast mode: Instr_(FAST, My$(ecx), "Hello", 0) ; 4 args, no startpos, modes 0+2 only
- case & mode (bitwise flag):
0=case-sensitive, +1=insensitive, +2=intellisense (Name=name),
+4=full word search, +8=include start of line in text block search
Note: full word search returns failure for chars above ASCII 64 to the left or right
Example: Nostructfoundhere, this123struct456isfound, this@struct, too
The FAST option is about twice as fast as CRT strstr, and three times
as fast when used with string arrays;
using FAST, binary search in haystacks containing zeros is possible by
assigning the buffer size to edx:
mov edx, LastFileSize ; any info on length of buffer can be used with edx
Print Str$("Pos in executable: %i", Instr_(FAST, esi, "kernel32", 2 or 64) ; 2=case-insensitive, 64=len in edx
- wRinstr is available but only as wRinstr(src, pattern) with a one-byte pattern (e.g. "\")
MasmBasic version 3 October (http://masm32.com/board/index.php?topic=94.0) features Enum$(), the companion to Enum:
Enum ; create a list of IDs
Enum IdMenuNew, IdMenuSave, IdMenuCopy, IdTimer
Enum 20:IdEdit, IdButton1, 30:IdButton2, IdStatic, IdFind, IdFindStatic
Remdefault start is 10, but (as shown above) new start values can be specified with nn:
Enum$ ; return numeric constant as text
Case WM_CREATE
Enum 20:IdEdit, IdButton1, 30:IdButton2, IdStatic, IdFind, IdFindStatic
; use with CreateWindowEx
Case WM_COMMAND
; ID is loword(wParam), print it as Enum$(ID, list of numeric constants)
PrintLine "command for control ", Enum$(word ptr wParam, IdEdit, IdButton1, IdButton2, IdStatic, IdFind, IdFindStatic)
mov ecx, Enum$(uMsg, WM_CREATE, WM_PAINT, WM_SIZE, WM_SIZING, WM_COMMAND)
.if byte ptr [ecx]!="?" ; if no matching entry is found, Enum$() returns a question mark
PrintLine "Message: ", ecx ; output e.g. Message: WM_PAINT
.endif
Below and attached a full example showing a practical use of Enum$().
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
uselib ntdll ; for RtlGetVersion
Init ; OPT_Assembler JWasm ; ML chokes with version suite string
sub esp, RTL_OSVERSIONINFOEXW-DWORD
push RTL_OSVERSIONINFOEXW ; set size member
invoke RtlGetVersion, esp
mov ecx, esp ; ecx is pointer to RTL_OSVERSIONINFOEXW structure
ovi equ [ecx.RTL_OSVERSIONINFOEXW] ; MSDN (https://msdn.microsoft.com/en-us/library/windows/hardware/ff563620%28v=vs.85%29.aspx)
.if eax
PrintLine "RtlGetVersion failed with ", Err$()
.else
PrintLine Str$("RtlGetVersion\t%i.", ovi.dwMajorVersion), Str$(ovi.dwMinorVersion), Str$(" SP %i.", ovi.wServicePackMajor), Str$(ovi.wServicePackMinor), Str$(" build %i", ovi.dwBuildNumber)
Print "Suite mask", Tb$, Hex$(ovi.wSuiteMask), ": "
For_ esi=0 To 31 ; see Geoff Chappell: The Product Suite (http://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/exinit/productsuite.htm)
xor eax, eax
bts eax, esi
and ax, ovi.wSuiteMask ; extra long line requires JWasm or AsmC (http://masm32.com/board/index.php?topic=902.msg50161#msg50161)
mov ebx, Enum$(eax, VER_SUITE_BACKOFFICE, VER_SUITE_BLADE, VER_SUITE_COMPUTE_SERVER, VER_SUITE_DATACENTER, VER_SUITE_ENTERPRISE, VER_SUITE_EMBEDDEDNT, VER_SUITE_PERSONAL, VER_SUITE_SINGLEUSERTS, VER_SUITE_SMALLBUSINESS, VER_SUITE_SMALLBUSINESS_RESTRICTED, VER_SUITE_STORAGE_SERVER, VER_SUITE_TERMINAL, VER_SUITE_WH_SERVER)
.if byte ptr [ebx]!="?"
Print Mid$(ebx, 11), " "
.endif
Next
PrintLine CrLf$, "ProductType", Tb$, Mid$(Enum$(ovi.wProductType, VER_NT_WORKSTATION, VER_NT_DOMAIN_CONTROLLER, VER_NT_SERVER), 8)
lea eax, ovi.szCSDVersion
wPrintLine "CSDVersion", wTb$, eax, wCrLf$ ; Unicode
.endif
add esp, RTL_OSVERSIONINFOEXW
Inkey CrLf$, "---- hit any key ----"
Exit
EndOfCode ; see MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/aa370663%28v=vs.85%29.aspx)
Output for Win7-64:
RtlGetVersion 6.1 SP 1.0 build 7601
Suite mask 0300: SINGLEUSERTS PERSONAL
ProductType WORKSTATION
CSDVersion Service Pack 1
XP - not much help - lol
i guess that would formatted as "5.1.2600 SP 3.0"
RtlGetVersion 5.1 SP 3.0 build 2600
Suite mask 0100: SINGLEUSERTS
ProductType WORKSTATION
CSDVersion Service Pack 3
Update 6 October: Inspired by James Fuller (http://bc9.bcxbasic.com/choose2.htm), the Choose command was added to the library:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
.data
tx123 db "This is tx123", 0
Init
mov ecx, Chr$("ecx is a string")
Dim My$()
Let My$(0)="array element 0"
Let My$(1)="array element 1"
.While 1
Inkey "Gimme a letter from a-z: "
.Break .if eax==VK_ESCAPE
xchg eax, ecx
.if Choose(ecx-"a", 100, 101, 102, "abc", 124, 12345.67, 12345678.90123456789, offset tx123, ecx, My$(1), "the letter k")<=ChooseString
.if eax==ChooseReal
Print Str$("You chose the real number %Jf\n", ST(0))
fstp st
.elseif eax==ChooseError
PrintLine "You typed the letter ", Chr$(ecx), " - error..."
.else
push eax
Print Str$("You chose the integer %i ", eax)
pop eax
PrintLine " (hex", Hex$(eax), ")"
.endif
.else
PrintLine "You chose the string [", eax, "]"
.endif
.Endw
EndOfCode
P.S.: VB Choose Function (https://msdn.microsoft.com/en-us/library/824bz7dy%28v=vs.90%29.aspx) on MSDN uses a double as the index - funny idea 8)
MasmBasic update of 11 October (http://masm32.com/board/index.php?topic=94.0) improves on its GUI interface:
GuiParas equ "Plotting a sinus and a map", x30, y30, w1200, h700, bnone
include \masm32\MasmBasic\Res\MbGui.asm
ToolTips ; initialise the tooltips, they will
ToolTips end ; show the country names
ArrayLoadMap 0, "\masm32\MasmBasic\Res\europe.map"
Event Paint
ArrayPlot hWnd, RgbCol(144, 240, 255) ; init with window (or control) handle and background colour
ArrayPlot 0, RgbCol(127, 127, 127), lines=2 ; display map #0 with grey borders 2px thick
ArrayPlot exit, "Europe" ; finish with a title
GuiTextBox 35.0, 92.0, 120, 32, "This application is sizeable - try it!!!!", fcol 0ffh, bcol RgbCol(204, 255, 204)
GuiTextBox 29.0, 63.0, 85, 66, "Move the mouse over a country to see its name", fcol 0, bcol RgbCol(255, 255, 128)
Event Message
.if uMsg==WM_MOUSEMOVE
ArrayMapRegion(lParam, 0, hWnd) ; activate tooltip if mouse enters a region
.endif
GuiEnd
Screenshot below. It's heavily sized, to save bandwidth - the full version looks better ;-)
i like the idea - but have no idea how it works - lol
i'd like to write a program that generates "great circle" maps (azimuthal equidistant)
they have them - they even have online generators, but i'd like my own
at any rate - no time to play with it for now :(
here's one, with the center on "some town" in France
they are different for every location in the world - lol
http://www4.plala.or.jp/nomrax/BM/Paris_l.gif (http://www4.plala.or.jp/nomrax/BM/Paris_l.gif)
we use them to "aim" our antennas
some guy in France wants to talk to a guy in Alaska, he aims his antenna about 350 degrees
Once upon a time, MSIE had a function that allowed to extract a table to Excel (the only reason I ever used Explorer instead of Firefox). That seems to have stopped working a long time ago, so I wrote a little proggie (70 lines) that does the job.
It is not for general use, though; some manual adjustment will be needed to download other tables. Here is the main loop that generates the string array (full code & exe attached, requires MB of 14 October 2015 (http://masm32.com/board/index.php?topic=94.0))
GetElements:
.While ct<maxcountries ; xs mode: use in loop, exclude left and right search strings
Let t$(ct, Rank)=Extract$(esi, '<td>', '</td>', xsLoop or xsExcL or xsExcR)
Let t$(ct, Country)=Extract$(esi, 'title="', Chr$(34, 62), xsLoop or xsExcL or xsExcR)
Let t$(ct, Int$)=Extract$(esi, '<td>', '</td>', xsLoop or xsExcL or xsExcR)
inc ct
.Endw
So if you are feeling strong in HTML, press Ctrl U in FF or MSIE and try to guess which left and right matches are suitable for extracting the table :P
P.S.: Download of the library (http://masm32.com/board/index.php?topic=94.0) appears to be disturbed today. I managed once to download and install with MSIE, but very, very slowly. FF downloads at under 3kB/s, and doesn't complete. Is it just my line, or have the Aussies been cut off from the Internet once more? The forum is also really slow today.
I was attempting to install your masmbasic library but the install screen is too large for my laptop screen. The max resolution for my laptop is 1366 x 768. I'm unable to see any buttons at the bottom of the screen to press to install masmbasic. Here is a screenshot:
(http://i62.tinypic.com/nn5zsg.jpg)
Just used my desktop to install your library and copied the files onto my laptop. Couple things I noticed.
- The ReadMeMasmBasic.txt shows the download location for JWasm at "http://www.japheth.de/JWasm.html#jwdownload" which seems to be an invalid location now.
- After replacing ml.exe with Jwasm.exe I received an error when attempting to assemble my program. Example of code where I encountered and error below:
.if eax == 1
do this
.elseif
do this
.endif
Now my .elseif should have been an .else in the first place but just wanted to let you know since it appears you wanted Jwasm to be a backwards compatible with microsofts ml.exe. Jwasm was just letting me know about my poor programming which microsofts ml.exe didn't care about.
Also just FYI. I'm sure you already know but Avast is throwing some fits about your installer.
Quote from: azdps on October 15, 2015, 01:52:02 AMI was attempting to install your masmbasic library but the install screen is too large for my laptop screen.
Thanks a lot for your feedback, azdps. The installer should be OK with version 16 October.
Quote- The ReadMeMasmBasic.txt shows the download location for JWasm at "http://www.japheth.de/JWasm.html#jwdownload" which seems to be an invalid location now.
- After replacing ml.exe with Jwasm.exe I received an error
That ReadMe is obsolete and will disappear soon. Re JWasm, just hit F6 when you see the manual, RichMasm will install JWasm. If Avast allows it, of course :bgrin:
And indeed, JWasm is occasionally a bit stricter than ML, but that's a feature IMHO. You may try also Nidud's AsmC, it's incredibly fast and seems to work fine now.
Version 16 October 2015 (http://masm32.com/board/index.php?topic=94.0): Fixed a few minor glitches in RichMasm, and re-installed the possibility to concatenate FileRead$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075) as in the snippet below.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
StringToArray FileRead$("\Masm32\include\Windows.inc")+FileRead$("http://masm32.com/board/index.php?action=help")+FileRead$("\Masm32\include\WinExtra.inc"), x$()
push eax
For_ ecx=0 To eax-1
.if Instr_(x$(ecx), "<head>", 1)
PrintLine "...", CrLf$, Str$(ecx), Tb$, "[", Left$(x$(ecx), 70), " ...]" ; print one line of the embedded HTML code
.endif
mov edx, stack
sub edx, 4
.if ecx<5 || ecx>=edx ; print first 5 and last 4 strings
.if Zero?
PrintLine "..."
.endif
PrintLine Str$(ecx), Tb$, x$(ecx)
.endif
Next
pop edx
pop edx
Store "ThreeFiles.txt", x$() ; write all strings to disk
ShEx "ThreeFiles.txt" ; show the result in Notepad
EndOfCode
jj2007 when testing the newest installer from the SetupMasmBasic17Oct15.zip the buttons now show at the bottom so it will install now. Just for testing purposes I pressed on the Masm32 Forum button and the program crashes and an error message box displays indicating the following: Setup.exe has stopped working. A problem caused the program to stop working correctly. Please close the program. I get the crash as well when clicking on close at the top right corner. The install button works without any issues.
I'm using Windows 8.1 32bit. Haven't tested it on my desktop which is running Windows 7 yet.
Thanks, azdps, for this information. It is indeed a bug, and I am trying to fix it right now.
EDIT: Fixed in version 19 October, please download and reinstall. (http://masm32.com/board/index.php?topic=94.0)
Extract$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1156) has now a wildcard option:
Let t$(ct, subject)=Extract$(esi, Chr$('class="subject"*"', 62), '</a>', xsWildcard)
Useful if you want to extract e.g. The Campus from
<a class="subject" href="http://masm32.com/board/index.php?board=1.0" name="b1">The Campus</a>
With the attached example, this output can be obtained:
The Campus Today at 07:48:01 AM Re: Calling an EXEs export functions
The Workshop Today at 07:56:53 AM Re: MasmBasic
The Laboratory Today at 07:02:35 AM Re: GetCpuFrequency Tests
The Soap Box Today at 11:45:25 AM Re: What base jumpers do when they grow up. :)
The Colosseum Today at 11:50:13 AM Re: Microsoft 'Accident' Forces Windows 10 Onto Windows 7, Windows
Please reinstall MasmBasic (safe, doesn't overwrite any user sources). This bug affects all versions before today:
include \masm32\MasmBasic\MasmBasic.inc ; download the good version (http://masm32.com/board/index.php?topic=94.0)
Init
Let edi="LMR"
Let esi=Mid$(edi, 2, 1)+Str$(0)+Mid$(edi, 2, 1) ; M0M, OK
PrintLine "[", esi, "]" ; Mid$+Str$+Mid$ ok
Let esi=Mid$(edi, 2, 1)+"/"+Mid$(edi, 2, 1) ; crappy result
PrintLine "[", esi, "]" ; 2xMid$ etc failed miserably before 20.10.2015
Exit
end start
In short, using Left$, Mid$ or Right$ twice with the same string as in Let My$=Left$(some$, somect)+Left$(some$, somect) caused trouble.
Sorry for the inconvenience. To compensate, I've improved the "Tiny GUI demo" that appears in menu File/New Masm source (34 lines of code, sizable window):
MasmBasic update of 23 October 2015 (http://masm32.com/board/index.php?topic=94.0) features major changes under the hood:
include \masm32\MasmBasic\Res\MbGui.asm ; OPT_Icon Plot
Dim MySinus() As REAL8
For_ ct=-400 To 400
SetFloat MySinus(ct+400)=Sinus(ct) ; *** a GUI demo in 24 lines of code ***
Next
Event Paint
ArrayPlot hWnd, RgbCol(192, 222, 255) ; init & set background
ArrayPlot MySinus(), 0, lines=5, 00100204h ; draw the array
ArrayPlot exit, "Playing with Sinus() plots" ; finish with a title
For_ ct=20 To GuiWidth-20 Step 10
GuiLine 50.0, 3.0+25, ct, 99.0, RgbCol(255, 160, 160) ; the 'pink pyramid'
void Cosinus(ct) ; load cos(ct) into ST(0)
fimul GuiHeight
fiadd GuiHeight ; center
fmul FP4(0.4)
SetInt ecx ; convert result to integer
GuiText ct+30, ecx+60, Str$(ct), bcol RgbCol(192, 222, 255)
GuiCircle ct, ecx+70, 1.5, b Rand(0ffffffh), p RgbCol(80, 80, 80)
Next
GuiEllipse 32.0+9, 10.0+35, 7.0, 8.0, b RgbCol(255, 128, 128) ; RGB for n00bs
GuiEllipse 60.0-9, 10.0+35, 7.0, 8.0, b 0FF2020h, p 808080h ; BGR for experts
GuiTextBox 50.0-70, 40.0, 140, 96, Str$("Painting took %i ms. This is just a simple text box, you can do the same in other programming languages", GuiMs), bcol RgbCol(255, 255, 192)
GuiCircle 50.0, 40.0+50, 12.0, p 0, b none ; none = hollow brush
EndOfCode
The window is sizable and flicker-free. The template is available via RichMasm's File/New Masm source list of templates, it's the "more" link behind "Tiny GUI demo".
RichMasm has now a full word search option, for distinguishing e.g. between edi and immediate. In the upper right corner, the FW check box switches it on (in case the toolbar is not wide enough to see the FW, press Ctrl G, type tbw=150 and hit Enter).
Update 30 October 2015 (http://masm32.com/board/index.php?topic=94.0) features minor improvements, inter alia the recognition of quoted strings like "123" and '123' as valid number formats, see StringToArray in \Masm32\MasmBasic\MbGuide.rtf:
; convert string to a numerical array:
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals a1$="123 27.5 28.49 -56.78 '20h' 0x40 11111b/123456789" ; string with a wild mix of number formats
Init
Dim MyDw() As DWORD
For_ ecx=0 To Fn(StringToArray a1$, MyDw())-1 ; strings to dwords conversion
PrintLine Str$("MyDw(%i)=", ecx), Str$(MyDw(ecx))
Next
EndOfCode
Output:
MyDw(0)=123
MyDw(1)=28
MyDw(2)=28
MyDw(3)=-57
MyDw(4)=32
MyDw(5)=64
MyDw(6)=31
MyDw(7)=123456789
Notes:
- StringToArray returns #elements in eax; in For_ ... Next loops, you may use Fn(...)-1 as shown above
- numeric arrays must be declared (BYTE ... QWORD, REAL4/8/10), but there is no need to Dim a string array before
Update 6 November changes the display of file timestamps (more (http://masm32.com/board/index.php?topic=4785.msg51603#msg51603)). Files that were modified during Daylight Saving Time now show the correct time, identical to the one displayed by Windows Explorer (which is in contrast to time shown by DOS and some file managers).
MasmBasic update 21 Nov 2015 (download (http://masm32.com/board/index.php?topic=94.0)) features several improvements under the hood. Check (in MbGuide.rtf) in particular the TimeSF and IsoWeek functions.
The RichMasm editor crashed on rare occasions when inserting a hyperlink with Ctrl K. This is fixed now.
Sometimes people post Hello World "projects" distributed over a dozen files. Apparently it looks more professional to put the three PROTO lines into separate include files.
When installing MasmBasic (e.g. the latest version (http://masm32.com/board/index.php?topic=94.0)), the first thing you'll see after clicking Accept & Install is the file MbGuide.rtf loaded with the RichMasm editor, as shown below (shortened).
Click the link "try 90+ snippets" to open MbSnippets.asc, a collection of over 90 "projects" (second image below). MasmBasic's editor has a very special feature: If the command Init is selected and you hit F6, it checks if there is an include ... line before and an end start or EndOfCode line afterwards. If both are found, the editor exports only the code between the two lines.
While the listbox has the focus, you can use cursor up/down to scroll through the "projects", which demonstrate some of the over 200 MasmBasic commands. If you see an interesting command, just hit F6 to see it in action :biggrin:
As a complement to GetRegKeyArray and GetRegArray (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1280):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Print "ct", Tb$, "ID", Tb$, "path"
For_ n=0 To GetProcessArray(?)-1
Print Str$("\n%i\t", n), Str$(MbProcID(n)), Tb$, MbProc$(n)
Next
Inkey CrLf$, "--- hit any key ---"
EndOfCode
Output:
ct ID path
1 324 \Device\HarddiskVolume3\Windows\System32\smss.exe
2 692 \Device\HarddiskVolume3\Windows\System32\wininit.exe
3 752 \Device\HarddiskVolume3\Windows\System32\services.exe
4 772 \Device\HarddiskVolume3\Windows\System32\lsass.exe
5 780 \Device\HarddiskVolume3\Windows\System32\lsm.exe
6 888 \Device\HarddiskVolume3\Windows\System32\winlogon.exe
7 924 \Device\HarddiskVolume3\Windows\System32\svchost.exe
8 992 \Device\HarddiskVolume3\Windows\System32\nvvsvc.exe
...
Source & exe attached, building requires latest MasmBasic version.
Quote from: jj2007 on May 23, 2012, 10:16:07 PM
MasmBasic is a library that allows to use BASIC syntax in assembler. . .
This is absolutely brilliant! I have been programming Intel processors in Assembly Language since 1975. In fact, hand-assembling the first few years. What I have always dreamed of, is using Microsoft 4k Basic syntax in assembly. Wow! This guy JJ is just awesome! He knows what everybody wants! I am thrilled!
i think Jochen has a new fan :biggrin:
At least one :P
Quote from: Oliver Scantleberry on November 28, 2015, 03:08:25 PMHe knows what everybody wants! I am thrilled!
Thanks, although I am not so convinced ::)
I would be stinkin' rich if that bold statement was true :bgrin:
MasmBasic version 2 December '15 features two new templates called Scintilla+RichEdit and WebCam. The latter is a bit long to post here, but here is a choice of three edit controls (plus a listbox) in less than 20 lines:
include \masm32\MasmBasic\Res\MbGui.asm ; OPT_Icon Smiley
GuiControl MySci, "scintilla", h 333, w 750, text "Привет, это контроль Scintilla" ; h 333 = 1/3 of height
GuiControl MyEdit, "edit", y 336, h 333, w 750, text "Это нормальная управления редактирования."
GuiControl MyRich, "richedit", y 672, h 333, w 750, text "Это контрольный RichEdit."
GuiControl MyListbox, "listbox", x 750, w 250
GetFiles *.asm ; fill Files$() array
SortFiles ; most recent on top
SetListbox "** select a file **"
SetListbox Files$()
SetGlobals cursel, f$
Event Command
.if IsTrue(LbSel ne cursel) && signed LbSel>0
m2m cursel, LbSel
Let f$=FileRead$(LbSel$)
SetWin$ hMySci=f$, sci
SetWin$ hMyEdit=f$
SetWin$ hMyRich=f$
.endif
GuiEnd
As you can see above, Unicode is fine for these controls, and with MasmBasic's RichMasm editor you can type Chinese or Russian or whatever directly into the source code.
The snippet assumes \Masm32\wscite\SciLexer.dll; add YOUR path before the GuiControl if needed, for example:
ScintillaPath equ "\Masm32\bin\SciLexer.dll"
The Scintilla DLL is available here (http://www.scintilla.org/SciTEDownload.html), see "A full download (1200K) includes the SciTE executable, any required DLLs". Extract to \Masm32\ to get the wscite folder and SciLexer.dll (the only file you need from the package to run the three edit controls example)
MasmBasic update 12 Dec 2015 features a major change under the hood: GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) returns now UTF-8 file names. This has no effect on file names using only Ansi characters, but it is a major improvement for those who use Russian, Chinese or Arabic file names (and that is quite a lot of people...). The snippet below shows its usage:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
SetCpUtf8
GfCallback MyCb ; set callback function for GetFiles
GetFiles \Masm32\*.bas|*.inc|*.as?|*.rc ; fill the Files$() array
PrintLine Str$("\n%i files found. Newest files:\n", eax)
SortFiles ; new files on top
For_ ecx=0 To eax-1
lea edx, [Files$(?)-10] ; somearray(?) means #elements
.if ecx<10 || ecx>=edx
If_ Zero? Then PrintLine CrLf$, "Oldest files:"
PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Files$(ecx)
.endif
Next
Inkey "---- hit any key ----"
Exit
MyCb: ; simple callback: ecx is file counter, esi current file in Unicode format
If_ wInstr(esi, wChr$("msv"), 1) Then wPrintLine esi ; demo for filtering output
ret
end start
Output (shortened):
comsvcs.inc
msv1_0.inc
msvcrt.inc
msvcrt.inc
msvcrt
8868 files found. Newest files:
327013 12.12.2015 01:14:55 \Masm32\MasmBasic\MasmBasic.inc
1985 12.12.2015 01:13:22 \Masm32\MasmBasic\AscUser\NewSources.asc
1032520 11.12.2015 11:25:24 \Masm32\RichMasm\RichMasm.asc
620 11.12.2015 08:18:32 \Masm32\MasmBasic\TestMasmBasic.rc
Oldest files:
288 07.09.1998 14:17:58 \Masm32\examples\exampl01\filtinpt\rsrc.rc
288 07.09.1998 14:17:58 \Masm32\examples\exampl01\comctls\rsrc.rc
288 07.09.1998 14:17:58 \Masm32\examples\exampl01\dll\loaddll\rsrc.rc
288 07.09.1998 14:17:58 \Masm32\examples\exampl01\3dframes\rsrc.rc
288 07.09.1998 14:17:58 \Masm32\examples\exampl01\dll\calldll\rsrc.rc
The snippet shows also how to use a callback function for GetFiles. If you return -111 in ecx, the current file will not be added to the Files$() array. Source & exe attached. Feedback, in particular from non-English members, appreciated :t
Quote from: jj2007 on December 12, 2015, 11:28:29 AM
MasmBasic update 12 Dec 2015 features a major change under the hood: GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) returns now UTF-8 file names. This has no effect on file names using only Ansi characters, but it is a major improvement for those who use Russian, Chinese or Arabic file names (and that is quite a lot of people...). . .
If I ever decide to program in assembly using Russian, Chinese, or Arabic, I will definitely give MbasicBasic a try. I'm right on top of Russian and Chinese but I need a little more work with Arabic. I keep reading it left to right.
MasmBasic update of 23 December 2015 (http://masm32.com/board/index.php?topic=94.0) improves and simplifies the use of Unicode & UTF-8 encoded charsets. This example shows recent sources in a listbox, and you can open them by double-clicking on an entry (source & exe attached):
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyLb, "listbox", y60, h940
GuiControl MyEd, "static", text "Double-click to open a file - Дважды щелкните, чтобы открыть файл", h50
GetFiles *.as?|*.rc ; asc, asm, rc
SortFiles ; latest files on top
SetListbox Files$() ; Fill the listbox with UTF-8 encoded file names
Event Command
If_ NotifyCode==LBN_DBLCLK Then uShEx LbSel$ ; open selected file with ShellExecuteW (u=assume UTF-8 for LbSel$)
GuiEnd
Second example (screenshot below, source attached) shows three edit controls: Scintilla, ordinary "edit" and RichEdit. The program is resizable, and the controls adjust their sizes proportionally based on this simple syntax:
GuiControl MySci, "scintilla", h500, x250, w300, text "... initial text ..."
GuiControl MyEdit, "edit", y500, h500, x250, w300, text "..."
GuiControl MyRich, "richedit", x550, w450, text "..."
GuiControl MyListbox, "listbox", w250
MyEdit, for example, is positioned at x=25% of client area, y=50%, 30% wide and 50% high.
MyListbox is positioned at default x+y positions, i.e. top left, full height and 25% width.
All i can say is WOW !!!!!
How you managed to hide the code from the rtf on right click ?
And the sinus example ! Loved it !
I launched NewSources and it told me
Quote
0 files found. Newest files:
---- hit any key ----
Does not like Frenchies this program!!!
The two others programs run OK.
Thank you, Guga, that was a nice feedback :P
But what do you mean with "hide the code from the rtf on right click" ?
Hmm...I found this feature while reading MasmBasic guide. The feature is the same behaviour as in Radasm.
In Radasm, when you click on a token or a macro ("If" macro or the ones marked with a "+" sign), the text is hidden. Ex:
If eax = 5
mov eax 1558
End_If
When you click in the "If" string, the text is hidden and it displays only this:
If eax = 5
End_If
Yours interface is different then in Radasm, but the behaviour is similar. What i liked on yours is the way we can actually read things on the richedit control. The ability to read the hyperlinks is great, and the way the help is displayed on certain mouse clicks, such this "hidden" of part of the text, or when you click on a string that may be a defined token and shows up a sort of help of what it is
On yours, I did this...before clicking on the word "Init"
include \masm32\MasmBasic\MasmBasic.inc
; hit F6 to assemble, link & run the Hello World example
Init
; to test examples, replace the white line with your test code and press F6
MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK ; It worked? Use a template, or try 90+ snippets
Print CrLf$, "OK - press any key" ; It choked? Read below about JWasm.
Exit
end start
After waiting 2 seconds, the mouse pointer changed to a question mark and it displayed this on a different color. (Also, the new text that shows can be scrolled. I simply loved that !:
include \masm32\MasmBasic\MasmBasic.inc
; hit F6 to assemble, link & run the Hello World example
Init
------------------------------------------------------------------------------------------------- <-------- This showed and it can be scrolled
Init This is perhaps the smallest possible complete Masm application:
include \masm32\MasmBasic\MasmBasic.inc
Init
Inkey "Hello World"
Exit
end start
Rem - the Init macro inserts the following two lines:
-------------------------------------------------------------------------------------------------<-------- This showed and it can be scrolled
; to test examples, replace the white line with your test code and press F6
MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK ; It worked? Use a template, or try 90+ snippets
Print CrLf$, "OK - press any key" ; It choked? Read below about JWasm.
Exit
end start
How you managed to do that on a richedit control ?????
Quote from: guga on December 24, 2015, 11:02:08 AMAfter waiting 2 seconds, the mouse pointer changed to a question mark and it displayed this on a different color. (Also, the new text that shows can be scrolled. I simply loved that !:
..
How you managed to do that on a richedit control ?????
Well,
two richedit controls ;-)
When you hover over a keyword, e.g. GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) *.asm, and you right-click when the cursor changes to
?, RichMasm displays, overlapping the main control, a second borderless richedit control containing the MbGuide.rtf content. If you are fast enough, you can even left-click into that content and actually copy the example code. I use that several times a day, it's much easier than typing the stuff... try it with SortFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1060) ;-)
Btw inserting a hyperlink is very easy: copy the URL, select a word in the comment area, hit Ctrl K, OK.
This year's last MasmBasic version (http://masm32.com/board/index.php?topic=94.0) does not only care for an exotic bug in the JWasm and AsmC assemblers (http://masm32.com/board/index.php?topic=4964.0) (or is ML wrong? who knows ::)), it also adds an interesting feature to the QSort string sort: You may use an index array to keep track of a string's original line number. Note this is not my idea, GfaBasic had it already in the mid-eighties; but MasmBasic is a bit faster: in case-insensitive mode, skipping leading spaces and using an index array, the routine sorts a Million strings in roughly one second on my Core i5 8)
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals c1, c2, c3
Init ; ## create a dynamic string array and sort it ##
Dim My$()
xor ecx, ecx
PrintLine "line", Tb$, "random string"
.Repeat
Let My$(ecx)=Str$("String %i", Rand(20)+1000)
PrintLine Str$(ecx), Tb$, My$(ecx)
inc ecx
.Until ecx>=10
QSortMode cis, sls, MyKeys() ; case-insensitive, skip leading spaces, use an index array
PrintLine CrLf$, "line", Tb$, "sorted string", Tb$, "was line"
QSort My$() ; sort all elements allocated so far
For_ esi=0 To ecx-1
PrintLine Str$("%i\t", esi), My$(esi), Str$("\t%i", MyKeys(esi))
Next
For_ esi=0 To ecx-1
Rand("A", "Z", c1) ; create three
Rand("a", "z", c2) ; random
Rand("a", "z", c3) ; chars
Let My$(esi)=Chr$(c1, c2, c3, "_")+Mid$(My$(esi), 6) ; rewrite string
Next
QSort My$() ; sort all elements allocated so far
PrintLine CrLf$, "line", Tb$, "resorted string", Tb$, "was line"
For_ esi=0 To ecx-1
PrintLine Str$("%i\t", esi), My$(esi), Str$("\t%i", MyKeys(esi))
Next
Inkey "OK?"
EndOfCode
Output:
line random string
0 String 1009
1 String 1001
2 String 1002
3 String 1017
4 String 1013
5 String 1016
6 String 1004
7 String 1015
8 String 1000
9 String 1010
line sorted string was line
0 String 1000 8
1 String 1001 1
2 String 1002 2
3 String 1004 6
4 String 1009 0
5 String 1010 9
6 String 1013 4
7 String 1015 7
8 String 1016 5
9 String 1017 3
line resorted string was line
0 Ebw_g 1017 3
1 Kia_g 1015 7
2 Ojo_g 1000 8
3 Olr_g 1002 2
4 Qgd_g 1001 1
5 Tvx_g 1010 9
6 Vdf_g 1009 0
7 Vny_g 1016 5
8 Xjo_g 1013 4
9 Ype_g 1004 6
Source + exe attached, plus an extended example showing how to use GuiImage:
include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit ; fit to window mode
GuiEnd
Inspired by Pelles C, I have written a plugin for RichMasm that zips the current source (including .rc, .inc etc if in the same folder) and copies the name of the zip file to the clipboard. It requires some zipper, e.g. 7-Zip (http://www.7-zip.org/download.html), and a recent MasmBasic installation (http://masm32.com/board/index.php?topic=94.0).
The attachment contains:
- a new version of RichMasm.exe, to be extracted as \Masm32\MasmBasic\RichMasm.exe
- ZipTheProject.dll and the source, to be extracted to \Masm32\MasmBasic\Plugins\ZipTheProject.dll
The plugin appears as last item in the System & plugins menu. For now, I have tested it with my 7z installation, and it works fine. Unicode file names work, too, but the name of the zip file will be e.g. ~tmpFile_12Jan.zip because 7z doesn't like UTF8 in the name of the archive.
Note that with 7-zip you can also use the extension .7z, with much better compression.
Work in progress, use at your own risk etc, feedback welcome 8)
First MasmBasic update this year (http://masm32.com/board/index.php?topic=94.0) 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.
P.S.: More recent versions of MasmBasic require that line 3, MyPie=100 gets deleted or commented out.
Why Read R1C1:R6C2 notprocessed?
It is not MasmBasic but RichBasic :badgrin:
Quote from: HSE on February 26, 2016, 02:45:02 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++ (http://www.softwareandfinance.com/Visual_CPP/Pie_Chart.html)
.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
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.
If your language is espanol, try using "F2C1:F9C2"
With Portuguese, it should be L2C1:L9C2 (more (http://cherbe.free.fr/traduc_fonctions_xl97.html) - look for row and column)
I attach the exe for Spanish.
Impressive ! :t
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:
## 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 (http://masm32.com/board/index.php?topic=94.0) 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.
Version 3 March 2016:
- DebugHeap now handles the infamous SHBrowseForFolder (http://masm32.com/board/index.php?topic=1169.msg11300#msg11300) 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
Recent versions of MasmBasic returned wrong results for the case-insensitive version of StringsDiffer() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1157), with consequences for QSort() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175).
Please reinstall (http://masm32.com/board/index.php?topic=94.0).
The good news is that the new version works correctly, is 40% shorter and 30% faster :biggrin:
Version 12 March has a new feature - sorting by a column's
value: (http://masm32.com/board/index.php?topic=94.0)
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, 3 [, 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 (http://masm32.com/board/index.php?topic=94.0)
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
EndOfCodeOutput: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() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) 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() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1202), 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)
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:
---------------- 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 (http://masm32.com/board/index.php?topic=94.0). 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.
Very nice JJ!
Give me a couple of years to study the macros :biggrin:
At first read it's unexpected that I obtain:
### line 343: case 19 : PrintLine "Case 19 (one line)",13,10 already defined ###
when I was expecting nothing or:
< not possible, use separate line ##>
This is my PrintLine:PrintLine MACRO args:VARARG
ifb <args>
print
else
print args, 13,10
endif
ENDM
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.
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)"
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
Post deleted per PM request
*** archive 28 April was temporarily removed - under certain conditions, the Switch_ macro would unbalance the stack ***
But it's fixed now - please reinstall (http://masm32.com/board/index.php?topic=94.0). Sorry for the inconvenience, and thanks again to HSE for informing me about the problem.
Please install MB version 6 May 2016: (http://masm32.com/board/index.php?topic=94.0)
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 (http://masm32.com/board/index.php?topic=94.0)
Init
PrintLine cfm$("years\tclassification") ; see #2, VB Case a<b (https://www.simple-talk.com/dotnet/.net-framework/10-reasons-why-visual-basic-is-better-than-c/)
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:
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.
MasmBasic version 14 May 2016 has two new features:
1. For each x$ in My$():
See demo here (http://masm32.com/board/index.php?topic=5361.msg57453#msg57453). Works with arrays of strings, integers, real numbers and structures (created e.g. with Dim myrc() As RECT)
2. Val("12, 45, 67", pos):
Imagine you have a line of settings in some ini file, and you want to know the value of the sixth entry... cumbersome, right?
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals settings$="0, 0, 1366, 768, 3, 123, 456, 789"
Init
Inkey Str$("The value of the 6th number is %i", Val(settings$, 6))
EndOfCode
Output:
The value of the 6th number is 123
Following this thread (http://masm32.com/board/index.php?topic=5383.0) about the Rich Edit control, and unexpected error messages in Windows 10, RichMasm got a minor revision of the way it loads RichEd20.dll
Please reinstall. (http://masm32.com/board/index.php?topic=94.0) The new function is available to MasmBasic users as invoke MbLoadRich. A simple window (<50 lines) with a Rich Edit control is attached; check the WM_CREATE handler, as shown below. In a nutshell: If you have MS Office or the free Word Viewer (https://www.microsoft.com/en-us/download/details.aspx?id=4) installed, loading a fat RTF file will be a factor 30-50 faster.
WndProc proc uses esi edi ebx hWnd, uMsg, wParam:WPARAM, lParam:LPARAM
SWITCH uMsg
CASE WM_CREATE
; picks the best RichEd20.dll available, or, if available, the one in the current folder:
invoke MbLoadRich
invoke CreateWindowEx, WS_EX_CLIENTEDGE, chr$("RichEdit20A"), NULL,
WS_CHILD or WS_VISIBLE or WS_BORDER or WS_VSCROLL or ES_MULTILINE,
9, 9, 570, 352, hWnd, 103, wcx.hInstance, NULL
ExternDef RichEditUsed:DWORD ; optional: check which version was installed
xchg eax, ecx
SetWin$ ecx=Cat$("This control was created using "+CrLf$+RichEditUsed)
Version 22 June 2016 (http://masm32.com/board/index.php?topic=94.0) features some improvements of the RichMasm editor (see here (http://masm32.com/board/index.php?topic=5314.msg58185#msg58185)), plus one new LineCount() macro and an improvement of PopCount() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1029).
LineCount - pretty fast, see timings (http://masm32.com/board/index.php?topic=3505.msg58276#msg58276)
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\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
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))
EndOfCode
Output:
In ebx, 8 bits are set: 10001000100010001000100010001000
In bx, 4 bits are set
In bl, 2 bits are set
The string
This
string
has
plenty
of
lines,
but
counting
them
is
easy
has 11 lines
MasmBasic version 30 June (http://masm32.com/board/index.php?topic=94.0) 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 (http://masm32.com/board/index.php?topic=5468.msg58624#msg58624) 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 (http://masm32.com/board/index.php?topic=94.0) 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\JBasic.inc
; ### simple console demo, assembles in 32- or 64-bit mode with ML64, AsmC, JWasm, HJWasm ###
j@start
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)
else
Print Chr$(" in 32-bit format", 13, 10)
endif
Print "Print Str$(123), CrLf: "
if 0
Print Str$(123), 13, 10 ; not possible
else
PrintLine Str$(123) ; much better ;-)
endif
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..."
j@end
; 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
Input$
Val arg$
Print args
PrintLine args
@AsmUsed$()
Err$()
Side-by-side assembly ;)
(in CreateWindowEx, the @64 variable sets the x coordinate to a different position)
Update 6 August (http://masm32.com/board/index.php?topic=94.0) features Inkey (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1109) and deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) 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$)
.endif
GuiEnd
For a speed test, see http://masm32.com/board/index.php?topic=5573.0
Update 15 August: (http://masm32.com/board/index.php?topic=94.0)
- 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: (http://masm32.com/board/index.php?topic=94.0)
- more complete dual 64/32 bit include files (no external libraries required)
- GetHash function:
include \masm32\MasmBasic\MasmBasic.inc
Init
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)
.else
PrintLine "Hashing failed: ", Err$()
.endif
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)
.endif
EndOfCode
- 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 (http://masm32.com/board/index.php?topic=94.0) - my apologies :redface:
Version 10 September 2016 (http://masm32.com/board/index.php?topic=94.0) 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 (http://masm32.com/board/index.php?topic=94.0) introduces two new macros, Alloc16 and Free16:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim PtrSSE() As DWORD
For_ ct=0 To A16Max-1 ; 100 aligned pointers
Alloc16 Rand(10000)
mov PtrSSE(ct), eax
Print Hex$(al), " "
Next
For_ ct=0 To A16Max-1
Free16 PtrSSE(ct)
Next
EndOfCode
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: (http://masm32.com/board/index.php?topic=94.0) The MasmBasic Switch_ macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1285) 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 (http://masm32.com/board/index.php?topic=5314.0) 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 (http://masm32.com/board/index.php?topic=94.0).
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
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 (http://masm32.com/board/index.php?topic=94.0) :icon_cool:
New features:
a) GuiImage (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1342) learned to care for resources, Unicode and the Internet (see attached Avatars.zip 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 "http://masm32.com/board/index.php?action=dlattach;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
GuiEnd
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
.endif
GuiRefresh
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)
GuiEnd
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 (http://masm32.com/board/index.php?topic=94.0)
GuiControl MySysLink, "SysLink", FileRead$("http://www.webalice.it/jj2006/MbLinks.htm")
Event Command
If_ NotifyCode==NM_CLICK Then wShEx Link$() ; open link in browser
GuiEnd
Update 7 November (download (http://masm32.com/board/index.php?topic=94.0)):
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
.else
inc rotatemode
.endif
.elseif wParam==VK_L
dec rotatemode
.if Sign?
m2m rotatemode, 3 ; 0->3
.endif
.elseif wParam==VK_S
dec savemode ; save image
.endif
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
RotateOrSave:
gdi+ GdipImageRotateFlip, gicbObj, rotatemode ; gicb stands for GuiImageCallBackObject
.if savemode
Clr savemode, rotatemode
SaveImageToFile wFiles$(imgCt)
.endif
retn
GuiEnd
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 http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar :eusa_dance:
To all who installed version 7 November: There was a little glitch with SaveImageToFile and Unicode file names. It's fixed, please install version 8 November (http://masm32.com/board/index.php?topic=94.0) (thanks to Mike for the inspiration :P).
The update allows also Unicode launches now, e.g. passing Chinese text to a MessageBox.exe in Russian:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Launch "Окносообщения.exe 您可以将中文文本传递到应用程序。"
EndOfCode
Attached two new examples - extract to a new folder, launch
a) LaunchUnicodeExes.exe (should produce what's shown in the screenshot)
b) ImageViewAndRotate.exe
to test them. Grateful for feedback 8)
Sources are included as *.asc files, building requires Masm32 and the latest November 9 MasmBasic. (http://masm32.com/board/index.php?topic=94.0)
Download update 26 Nov 16: (http://masm32.com/board/index.php?topic=94.0)
Inter alia, GuiImage handles now animated GIFs automatically; search \Masm32\MasmBasic\MbGuide.rtf for .MbGui
Example (attached):
GuiParas equ "GuiImage demo", x100, y100, w540, h180, bnone, m0, deb0 ; no background, margin zero, debug 0
include \masm32\MasmBasic\Res\MbGui.asm ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
Event Paint
GuiImageSpeed 200 ; animation speed 200%
GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit ; background
GuiImage "http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar", 300, 64, 40, 40
GuiImage "\masm32\MasmBasic\icons\Smiley.ico", 118, 40, 32, 32
GuiImage 48, 170, 56, 64, 64 ; resID, x y w h
GuiEnd
Rsrc ; **** during assembly, RichMasm exports this section as filename.rc ****
32512 ICON "\\masm32\\MasmBasic\\icons\\Globe.ico"
48 RCDATA "Shooter.gif"
Rsrc
The demo displays
- a static background car.jpg
- an avatar (members only, sorry :biggrin:)
- a smiley (the car needed a little decoration)
- and an animated GIF from the resources
Version 30.11.16 (http://masm32.com/board/index.php?topic=94.0) adds a new functionality to the StringToArray (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1130)command:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="Open" ; just an example: Open "O", #1, "somefile.txt"
StringToArray 123, mbi$() ; 123 is the resource ID
.While 1
Let esi=Input$("Search for macro: ", esi)
.Break .if Len(Trim$(esi))==0
push mbi$(?) ; #elements on stack
xor ecx, ecx
Cls
.Repeat
.if Instr_(mbi$(ecx), esi, 1)==1 ; case-insensitive search
.Break .if Instr_(mbi$(ecx), "macro", 5) ; case-insensitive, full word
.endif
inc ecx
.Until ecx>=stack
dec ecx
.Repeat
inc ecx
PrintLine mbi$(ecx)
.Until Instr_(mbi$(ecx), "endm", 5)==1 || ecx>=stack
pop edx
.Endw
Print "bye"
Delay 500
EndOfCode
Rsrc ; when hitting F6, RichMasm exports this section to [filename].rc
123 RCDATA "\\Masm32\\MasmBasic\\MasmBasic.inc"
Rsrc
In this snippet, StringToArray converts an embedded text file (MasmBasic.inc) to a string array.
Project is attached, including the rc file, which is not needed if you build the source with RichMasm.
Update 12 December (http://masm32.com/board/index.php?topic=94.0) features an improved handling of toolbars, see an example in the small editor thread (http://masm32.com/board/index.php?topic=5858.0).
One new feature, you can extract a file from resources:
FileWrite "MyFile.txt", "MyString" ; opens a file and writes a string to file
FileWrite "MyFile.txt", "MyString", 2 ; same but writes only first 2 bytes
FileWrite "MyFile.rtf", stream:hRichEdit ; save contents of the RichEdit control
FileWrite "MyFile.uctxt", stream:hRichEdit, SF_TEXT or SF_UNICODE ; same but specify a format
If_ Not Exist("build.bat") Then FileWrite "build.bat", res:99 ; extract a file from RCDATA resource #99
FileWrite "MyFile.txt", "MyString", xmm0 ; sets the timestamp in xmm0
Rem returns Close retval in eax and bytes written in edx
Update 16 December is inspired by Caballero's Ancient DOS sounds (http://masm32.com/board/index.php?topic=5866.0) thread and uses the new 'get a string array from resources' feature:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0) (needs version 16 December 2016 or later)
Init
StringToArray 123, music$() ; get an array from resources
For_ ct=0 To eax-1
Sound music$(ct)
Next
EndOfCode
Resources:
32512 ICON "\\Masm32\\MasmBasic\\icons\\Smiley.ico"
123 RCDATA "Song4MasmBasic.txt"
The attachment contains a Pelles C source (BeepWC01.asc) based on Caballero's version for Tiny C. The switch #define Export2MasmBasic 0 in line 2 allows to export his sound as a text file with entries meaning pitch:duration:pause:
1045:250:100
650:250:100
650:250:100
1045:250:100
1045:1000:100
650:250:100
Please install update 20 December 2016 (http://masm32.com/board/index.php?topic=94.0); inter alia, new events Data and DropFiles were added:
Event Data ; WM_COPYDATA
MsgBox 0, CopyData$, "Received:", MB_OK
Event DropFiles ; loads the Files$() array; use wRec$() to convert Utf8 file names to true Unicode
wMsgBox 0, wCat$(wStr$("%i files dropped, first one is\n[", Files$(?))+wRec$(Files$(0))+"], last one is "+CrLf$+"["+wRec$(Files$(Files$(?)-1))+"]"), "Event Dropfiles:", MB_OK or MB_TOPMOST
Store "~tmpDropped.txt", Files$() ; write dropped filenames to a text file in Utf8 format
As with GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056), file names obtained in the DropFiles Event are in Utf8 format.
MasmBasic update 29 December 2016 is out, please reinstall.
In honour of the "Editor for testing (http://masm32.com/board/index.php?topic=5858.0)" thread, I've added a new handy macro:
Print "This application uses ComCtl32.dll version ", ComCtl32$()
Output: This application uses ComCtl32.dll version 6.16 (provided your resources and manifests are 100% ok :icon_mrgreen:)
Found a weird bug on the latest (29 December 2016) version:
While RichMasm is opened, if you click the "X" button, RichMasm won't quit, but only minimze itself instead.
Gotta terminate it manually using Task Manager.
Happens on 32-bit Windows 10.
It's not a bug, it's a feature :P
Seriously: MbGuide.rtf is a special document, it will only minimise if you try close it. But if you close it while it is minimised, it will indeed close (besides, it will also close if no other docs are open in RichMasm).
The reason for this special behaviour is that it also serves as "F1 help". Select a keyword, then hit F1:
- if it's a MasmBasic keyword like Print, the paragraph on Print will be displayed in MbGuide.rtf
- if it's not found in MbGuide.rtf, e.g. CreateWindowEx, RichMasm will pass on the request to the program that follows in \Masm32\MasmBasic\Res\menus.ini, i.e. Win32.hlp:
[&Help]
&Basic,\masm32\MasmBasic\MbGuide.rtf#Mb
&WinHLP32,\Masm32\RichMasm\Help\WIN32.HLP
Thus, you get most of the time the help you expect, simply by selecting the keyword and hitting F1.
Note that for the MasmBasic keywords, about 200, RichMasm has another mechanism: Hover over the keyword, e.g. GetFiles, until the mouse cursor turns into a question mark. Then right-click (I'm afraid this is case-sensitive, so getfiles will work only with F1).
Just found a lengthy article on Printing text in Win32 can be a little complicated (http://www.masmforum.com/board/index.php?topic=9364.msg68003#msg68003) posted by Paul Brennick over 8 years ago - I wish I had seen it earlier, it would have saved me a lot of work :(
Anyway, here is a simple method to print the content of a RichEdit control. This snippet reads a file from the commandline, and if you hit Ctrl P, its contents get printed - not in the sense of console print, but in the sense of: on real paper. Here is the source:
include \masm32\MasmBasic\Res\MbGui.asm ; download (version 5 January 2017 or later) (http://masm32.com/board/index.php?topic=94.0)
GuiControl MyEdit, "RichEdit" ; create a RichEdit control
If_ wExist(wCL$()) Then <SetWin$(hMyEdit)=wFileRead$(wExist$)>
Event Key
If_ KeyCtrl && (VKey==VK_P || VKey==-VK_P) Then <MsgBox 0, Str$("%i pages printed", PrintRtf(hMyEdit, 2)), "PrintRtf:", MB_OK>
GuiEnd
Full project attached. The PrintRtf() macro needs a handle to a RichEdit control, and takes optional parameters as follows (excerpt from \Masm32\MasmBasic\MbGuide.rtf):
- if text is selected, then only the selection will be printed
- optional second arg: 0=use default printer, 1=use once the printer dialog, 2=use it always
- optional: margins in mm, e.g. void PrintRtf(hMyEdit, 0, 20, 20, 15, 20) ; left, top, right, bottom
- printer settings like orientation etc are kept for the program's duration
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0) (version 11 January 2017 required)
Init
UnzipInit "http://www.terraspace.co.uk/hjwasm217_x86.zip"
.if Sign?
Print eax ; print an error message
.else
For_ ecx=0 To edx-1 ; #files returned in edx
mov esi, Files$(ecx)
.if Rinstr(esi, "/") ; zipfiles use forward slashes
xchg eax, esi ; we don't display the full path
inc esi
.endif
PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, esi
.if Instr_(esi, ".pdf", 1)
UnzipFile(ecx, Cat$(Left$(MbExeFolder$)+":\Masm32\bin\"))
ShEx Cat$("\Masm32\bin\"+esi)
.endif
Next
UnzipExit
.endif
EndOfCode
With certain types of Unicode text files, Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) added garbage to the last string read. This is fixed with MasmBasic version 27 Jan 2017 - please reinstall (http://masm32.com/board/index.php?topic=94.0). The following will work properly now:
include \masm32\MasmBasic\Res\MbGui.asm ; download (http://masm32.com/board/index.php?topic=94.0)
Recall "http://www.webalice.it/jj2006/DemoChinese.dat", L$()
Event Paint
For_ ct=0 To L$(?)-1
GuiText 7, ct*16+7, Str$("# %i ", ct+1)
GuiText 90, ct*16+7, L$(ct)
Next
GuiEnd
The snippet above downloads the text from my personal website. Here is a variant where Chinese text is used in $Data statements:
GuiParas equ "A Chinese Poem", x300, y70, w300, h125, bRgbCol(255, 255, 222)
include \masm32\MasmBasic\Res\MbGui.asm
$Data 月夜
$Data 霜风呼呼地吹着,
$Data 月光明明地照着。
$Data 我和一株顶高的树并排立着
$Data 却没有靠着 。
Read poem$() ; translate $Data elements to a string array
Event Paint
For_ ct=0 To poem$(?)-1
GuiText 7, ct*16+7, Str$("# %i ", ct+1) ; display the array elements
GuiText 60, ct*16+7, poem$(ct)
Next
GuiEnd
The screenshot shows how it looks like in RichMasm and in the little window created by the above code.
Projects attached, feedback welcome of course.
Update 1 February (http://masm32.com/board/index.php?topic=94.0) fixes two bugs:
1. One minor bug with Chr$("The letter is ", reg32): if reg32 was edi, the displayed letter was wrong. This works now (attached):
GuiParas equ "Key events only", x50, y50, w100, h60, s0
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyStatic, "static"
Event Key
SetWin$ hMyStatic=Chr$("You pressed ", VKey) ; requires MasmBasic of 1 February 2017 (http://masm32.com/board/index.php?topic=94.0)
GuiEnd
2. Val (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1202)() and MovVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1203)() returned -127 (error) in edx for the string 0 if there was text after the zero delimiter, e.g. sometext db "0", 0, "more text"
New FindProcess() function:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
.if FindProcess("Explоrer.exe")
Inkey Str$("FindProcess returned ID %i\n", [eax.PROCESSENTRY32.th32ProcessID])
.else
Inkey "Process not found, error: ", Err$()
.endif
EndOfCode
Attached a demo: Extract all files to a folder and launch first Explorer.exe (don't close the MsgBox), then the FindProcessDemo.exe
The macro is still based on Tim's example (http://masm32.com/board/index.php?topic=5985.msg63494#msg63494), although I managed to bring it down to exactly 80 bytes, using three (!) times the extremely old xchg instruction :biggrin:
Don't worry, the explorer.exe won't do any harm to your machine. Really :P
You can see it in Olly if you don't trust me; or look at Jotti's scan results (https://virusscan.jotti.org/en-US/filescanjob/1efkn8p4xf)
Sorry, no manifest, no vcb, "0/18 scanners reported malware" ... although, an intelligent AV should indeed shout foul 8)
EDIT: Explorer source added
Pardon my ignorance. How to quit the RichMasm gracefullly?
I assume you need not to use the Task Manager :redface:
Hit Alt F4
For a while, RichMasm had forgotten how to display tooltips :(
Fixed with version 21 Feb 2017 - please reinstall. (http://masm32.com/board/index.php?topic=94.0)
Quote from: jj2007 on February 08, 2017, 02:48:59 AMan intelligent AV should indeed shout foul 8)
Interesting that nobody asked why... check the filename Explorer.exe very, very carefully. You may find out that the o is not the usual one. The whole AV battery at Jotti's found nothing to complain, which confirms my theory that they cooperate closely with the malware scene. It's called a "business model" :P
Since full Unicode support was introduced some days ago, RichMasm had a problem with commandline arguments: If there was e.g. an OPT_Arg1 test.gif in the text, it created files named myname.exe test.exe instead of myname.exe
Fixed with MasmBasic update of 25 February, please reinstall (http://masm32.com/board/index.php?topic=94.0)
Update 1 March 17 (http://masm32.com/board/index.php?topic=94.0) fixes a minor issue with the handling of 64-bit code (http://masm32.com/board/index.php?topic=5314.msg59884#msg59884), and adds the PushText macro (http://masm32.com/board/index.php?topic=5799.msg63987#msg63987).
Hi JJ,
I wrote this little prog for my Ascii game. It compresses the txt file even more than I got the last time (original= 89.999, new size= 4.323).
I´s all good but I have a question.
I´m using (for the first time) the Switch case MACRO from MasmBasic (masm32 didn´t like how I did it):
Quote
Quote ;========== FILTER UNWANTED CHARS ====================
xor edi, edi
filter:
mov bl, BYTE Ptr [esi + edi]
Switch_ bl
Case_ '='
mov bl, " "
Case_ 60, 62
mov bl, '@' ; chars < , > (bombers)
Endsw_
add edi, 1 ;add counter
cmp edi, tLen ;end of file?
jnz filter
All good except from one thing: My file got 23kb fatter with MasmBasic. 26kb as opposed to 3kb with masm32rt.
Am I missing something?
By the way, check this colour set up, it´s really nice to work with.
Cheers,
Alex
Quote from: LordAdef on March 02, 2017, 06:10:59 PMAll good except from one thing: My file got 23kb fatter with MasmBasic. 26kb as opposed to 3kb with masm32rt.
It's the 20k overhead of common functions like e.g. array handling. In exchange, you get interesting stuff like the Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) and Store (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1174) pair, or, most important, the deb macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) ;)
QuoteBy the way, check this colour set up, it´s really nice to work with.
Looks nice indeed.
Btw, compliments, you are making big progress. Coding RLE in assembler is not a beginner's job :t
Update 3 March:
- RichMasm works again as it should under Windows XP (F6 used to build code, but it wouldn't run it...); there were no problems under Win7 and Win10
- ComCtl32$() takes now an optional format string:
include \masm32\MasmBasic\MasmBasic.inc
Init
Inkey ComCtl32$("This program uses ComCtr32.dll version %3f\ncheck your manifest if you expected a higher version")
EndOfCode
Without a manifest, you will see the old pre-XP version of the common controls dll:This program uses ComCtr32.dll version 5.82
In RichMasm,
- go to the end of the file
- click on menu AutoCode, Resources: manifest (this inserts a Rsrc section, including a manifest)
- hit F6 again to seeThis program uses ComCtr32.dll version 6.16
As mentioned in the Manifests in 64-bit land (http://masm32.com/board/index.php?topic=6047.0) thread, the same manifest works also for 64-bit assembly. Even the 32-bit example that uses 64-bit code works fine with this manifest. (http://masm32.com/board/index.php?topic=6037.msg63972#msg63972)
Update 6 March brings a new feature: the FileProp$() array.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Print "Searching ", ExpandEnv$("%ProgramFiles%"), " ..."
GetFiles ExpandEnv$("%ProgramFiles%\ms*.exe|ms*.dll") ; limit to all executables starting with ms
deb 4, "** files found", eax
For_ ct=0 To Min(999, eax-1) ; max 1000 files
mov ecx, Files$(ct)
GetFileProps ecx
.if FileProp$(?)>1 ; more than one file property found
.if Rinstr(ecx, "\")
inc eax ; put eax after the \
xchg eax, ecx ; we don't show the full path
.endif
Print ecx ; the filename
PrintLine At(40) FileProp$(FileDescription)
.endif
Next
PrintLine CrLf$, "Finally, all properties of the current file:"
GetFileProps ; no args = current file
For_ ecx=0 To FileProp$(?)-1
Print Str$("%_i ", ecx), FilePropName$(ecx)
PrintLine At(30) FileProp$(ecx)
Next
Inkey "ok?"
EndOfCode
Typical output:Searching C:\Program Files (x86) ...
** files found eax 630
msvcp60.dll Microsoft (R) Visual C++
msvcp71.dll Microsoft® Visual Studio .NET
msvcr71.dll Microsoft® Visual Studio .NET
msvcp80.dll Microsoft® Visual Studio® 2005
msvcr80.dll Microsoft® Visual Studio® 2005
msvcp71.dll Microsoft® Visual Studio .NET
msvcp80.dll Microsoft® Visual Studio® 2005
msvcr71.dll Microsoft® Visual Studio .NET
msvcr80.dll Microsoft® Visual Studio® 2005
msvcp71.dll Microsoft® Visual Studio .NET
msvcr71.dll Microsoft® Visual Studio .NET
MSVCP60.DLL Microsoft (R) Visual C++
msvcrt.dll Microsoft (R) Visual C++
MSDEUI.DLL Microsoft Data Environment 1.0
MSADDNDR.DLL AddInDesigner Object Library
MSDE.DLL Microsoft Data Environment 1.0
MSDERUN.DLL Microsoft Data Environment Runtime 1.0
MSHTMPGD.DLL DHTMLPageDesigner Object Library
MSHTMPGR.DLL DHTMLPageDesigner Object Library
MSWCRUN.DLL WebClass Runtime Object Library
MSOEURO.DLL Microsoft Office 2003
mshwgst.dll Microsoft® Windows® Operating System
mshwLatin.dll Sistema operativo Microsoft® Windows®
MSPFLTRS.DLL Microsoft Office Document Imaging
...
MSSP7SW.DLL Natural Language Components
mssp7tr.dll Natural Language Components
msoe.dll Microsoft® Windows® Operating System
MSOERES.dll Sistema operativo Microsoft® Windows®
Finally, all properties of the current file:
0 Lang 080904B0
1 Comments This is a comment
2 InternalName Internal name
3 ProductName Jochen's Assembly Tools Collection
4 CompanyName MasmBasic
5 LegalCopyright © 2017 Jochen@Masm32
6 ProductVersion Release version 6 March 2017
7 FileDescription Testing FilePropDemo
8 LegalTrademarks ?
9 PrivateBuild ?
10 FileVersion 1.0
11 OriginalFilename FilePropDemo
12 SpecialBuild ?
Demo attached. Open in RichMasm, hit F6 to build it. Remove the "ms" in GetFiles to get all executables 8)
So hi! I am starting to learn asm and i have just found MasmBasic and to be honest after problems with VS (still cant set up subsystem) I am happy with it. But is there an possibility to change resolution of this (http://i.imgur.com/dJTXHEH.png)?
And is there an way to customize colors of background of text? I want to make it darker. Thanks!
Quote from: Spamm3r on April 15, 2017, 12:04:41 AMBut is there an possibility to change resolution of this
What exactly do you mean with "resolution"? Does it look better if you hold Shift when opening a file, and use "screenshot mode"?
QuoteAnd is there an way to customize colors of background of text? I want to make it darker. Thanks!
Ctr G, udc=14, <Return>
This fellow programmer reminds me of my suggestion of some colour tabs... remember?
Any chance of you giving us this powerful colour enhancement?
http://masm32.com/board/index.php?topic=6055.msg64384#msg64384 (http://masm32.com/board/index.php?topic=6055.msg64384#msg64384)
Quote from: LordAdef on April 16, 2017, 08:33:38 PMAny chance of you giving us this powerful colour enhancement?
Real Men
TM select the text, hit Ctrl G and type col=ff8000h :P
Any chance to get more sharp titles (I mean, file, edit etc) Beacuse on 1920x1080 they are not sharp...
Sharp titles: If you hold Shift when opening a file e.g. from the recent files list, and confirm "screenshot mode", do they look better? There is a problem with the Gdi+ font that I use to work around Aero...
Quote from: jj2007 on April 17, 2017, 04:29:09 AM
Quote from: LordAdef on April 16, 2017, 08:33:38 PMAny chance of you giving us this powerful colour enhancement?
Real MenTM select the text, hit Ctrl G and type col=ff8000h :P
and how do the Real Men set the bk colour?
Quote from: LordAdef on April 17, 2017, 04:40:21 PM
and how do the Real Men set the bk colour?
Ha :t
You are getting ambitious here :icon_mrgreen:
1. Make a copy of
\Masm32\MasmBasic\Res\RichMasm.ini and place it in
\Masm32\MasmBasic\Res\UserDef\RichMasm.ini
2. Edit the lines under udc=nn, i.e. lines 18 to 25
3. Restart the editor.
That's for the document background. In case you want different backgrounds for individual sentences:
1. Try that in Micros**t Word (and tell me if that is possible :bgrin:)
2. Paste the result in RichMasm.
As mentioned in the 124 bugs thread (http://masm32.com/board/index.php?topic=5382.msg65319#msg65319), I need to add a warning that mat=0 destroys the work. If I find the time, I
may add a Ctrl G bgc=bbggrrH function, too.
Attached a beta for
you, Alex 8)
Thanks JJ, I will try that.
QuoteYou are getting ambitious here :icon_mrgreen:
Nice one! ::)
I use the Office trick often, it works.
Do you have plans to implement that infamous colour tab as we talked about in the other thread? That would be a great for a future upgrade version.
Quote from: LordAdef on April 18, 2017, 03:24:31 AMDo you have plans to implement that infamous colour tab
No, but I have a little project for you (http://masm32.com/board/index.php?topic=5314.msg63462#msg63462) ;)
Hi JJ,
I just checked the beta you sent it. The UserDef worked! Thanks
But the Beta didn`t build my project.
When you say a "Beta for you", is it something related to the colour things we were talking about it? I didn´t see the difference.
ps (And I´m still using an old version of RM... I´ve got to update it but it was running so nicely I didn´t stop to do it)
Quote from: LordAdef on April 22, 2017, 06:40:50 PMBut the Beta didn`t build my project.
What happened? Details please 8)
QuoteWhen you say a "Beta for you", is it something related to the colour things we were talking about it? I didn´t see the difference.
Hey, that was ages ago :P I can't remember what was "beta" at that moment. Anyway, current version is online (http://masm32.com/board/index.php?topic=94.0) and works like a charm.
QuoteWhat happened? Details please
Never mind, I´ve downloaded the latest version and everything is sweet!!
I got it=> you got the code for "bgc=" in there, right? That´s niice.
I know we are doing BGR, but would it be possible in the future to invert it to RGB? A lot more convenient when using color pickers that returns you the Hex values, and they usually do it in RGB. It´s only a Copy/Paste.
I like this online one, check it out, quite convenient: https://www.webpagefx.com/web-design/color-picker/a1d490 (https://www.webpagefx.com/web-design/color-picker/a1d490)
Hmmmm... what about bgc=? and col=? instead of an online colour picker?
Of course, this requires major changes in the RichMasm source ::)
void Val(esi)
...
.if edx==-127 ; user typed col=? or bgc=?
void RgbCol(?) ; let the colour picker do it
.endif
that would be fantastic!
Update 24 April (http://masm32.com/board/index.php?topic=94.0) features a new option for the RgbCol macro:
QuoteRgbCol, CgaCol, SysCol
mov eax, RgbCol(ebx, 0, 0) ; any mix of reg32, vars and immediates is allowed
mov bl, 127 ; only bl will be used
invoke SetTextColor, hDC, RgbCol(ebx, 0, 0) ; Red Green Blue for Gdi32 functions
invoke SetTextColor, hDC, SysCol(ebx) ; use the system palette
invoke SetTextColor, hDC, RgbCol(?) ; use the colour picker
mov hPG, rv(GdipCreatePen1, RgbCol(alpha, red, green, blue), FP4(3.0), UnitWorld, addr pPen)
Rem - Gdi functions want RGB values, i.e. three parameters
- in contrast, GdiPlus expects ARGB, i.e. four parameters; the first one, alpha, defines
transparency ranging from 0=fully transparent to 255=opaque
- CgaCol(index) may be used with console colours; see ConsoleColor for identifiers
- SysCol(index) returns a GetSystemPaletteEntries colour for use in Gui applications
See Reply #393 above for an application in RichMasm - greetings to Alex :biggrin:
(the void avoids a mov eax, eax)
===== THIS IS SO NICE JJ!!!! Thanks a lot ======
ps: edit to add: I mean this is reeeeally nice! Now I see RichMasm "flying clolours" :greenclp: :eusa_clap: :eusa_dance:
Don't overdo it, Alex. Rich text is certainly better than poor text, but with a lot of experience, I limit the use of colour nowadays to MB keywords, push/pop pairs (easier to see if the stack is balanced), and a few very specific tricky code consequences. Btw you can see this "default use" when selecting a block of text and hitting F4 aka "comment" twice.
Another example - red for @Backwards, blue for @Forward jumps (I prefer .Repeat ... .Exit .if ... .Until, though):
xchg eax, ebx
@@: dec edx
jl @F
stosb ; insert new empty elements
jmp @B
@@: xchg eax, edi
pop ebx
This helps to grasp how the loop works. It is much more important to have this visual aid when the loop spans over 20 or 50 lines, of course.
Christmas tree looks nice at first sight, but it doesn't help to focus attention on the really important parts. Which applies, btw, also to the VS or Scintilla style automatic highlighting.
QuoteDon't overdo it, Alex. Rich text is certainly better than poor text, but with a lot of experience, I limit the use of colour nowadays to MB keywords, push/pop pairs (easier to see if the stack is balanced), and a few very specific tricky code consequences.
Oh, don´t worry. In fact I never did it. But it´s invaluable for temporary modifications. I usually colour when trying things out. Later, when things look right, I bring them back to default.
I´m posting my game there at my thread, you will see it´s being used carefully.
Quote from: LordAdef on April 24, 2017, 10:28:42 PMit´s invaluable for temporary modifications
Exactly :t
What I frequently use:
if 1 ... 50 lines of active code ...
else ... 50 lines of alternative code ...
endif
JJ,
only FYI, a behaviour I don't recall from the previous 2 versions but now in place:
If you select some code and build (while the code is still selected) it generates an error. I found this by chance when selecting some code, F4 and build. The commented bit must be unselected now in order for the build to be successful.
Nothing out of this world, but I thought I should let you know.
Quote from: LordAdef on April 25, 2017, 09:03:16 PMIf you select some code and build (while the code is still selected) it generates an error. I found this by chance when selecting some code, F4 and build. The commented bit must be unselected now in order for the build to be successful.
It's not a bug, it's a feature :lol:
Insert this somewhere in one of your sources:
if 0
include \masm32\MasmBasic\MasmBasic.inc
Init
Inkey "Current time is ", Launch$("cmd /c time /t")
EndOfCode
endif
The
if 0 ... endif comments it out, so it won't disturb building your source. But if you select the lines inside and hit F6, then only the lines
include ... EndOfCode will be used for the assembly. Useful for testing little snippets, but I will add a warning to the output window explaining why there was an error...
Updated as instructed! :dazzled:
MasmBasic update 11 May features several improvements of Unicode handling (http://masm32.com/board/index.php?topic=94.0). Inter alia,
- you can write strings in any language directly in the editor;
- file names can be in any language, too;
- find & replace is now Unicode aware.
The snippet below is a full-fledged Windows application. Please test in particular the FileOpen() feature.
GuiParas equ "严重的软件应该使用Unicode!!!!", h400 ; in RichMasm, hit F6 to build this application
GuiMenu equ <@File, Open, Save, Save &as, E&xit> ; requires MasmBasic (http://masm32.com/board/index.php?topic=94.0)
include \masm32\MasmBasic\Res\MbGui.asm
MakeFont hFont, Height:24
GuiControl MyEdit, "RichEdit", font hFont, wCat$("The commandline passed was"+CrLf$+wCL$())
Event Menu
Switch_ MenuID
Case_ 0 ; first menu item has index 0
.if wFileOpen$("богатый источник=*.asc|Poor sauce=*.asm|资源=*.rc", "богатый источник")
SetWin$ hMyEdit=wFileRead$(wFileOpen$())
.endif
Case_ 1, 2: MsgBox 0, "Saving not implemented, sorry", "Hi", MB_OK
Case_ 3: invoke SendMessage, hWnd, WM_CLOSE, 0, 0 ; yes, you can use pure assembler ;-)
Endsw_
GuiEnd
Demo attached. To test it, extract to \Masm32\MasmBasic, then drag the file with the exotic name over \Masm32\MasmBasic\UnicodeIsEasy.exe
Quote- find & replace is now Unicode aware.
Since you mentioned find & replace, let me report this one for FYI sake:
"find" now finds key words in INCLUDE files (with Capital letters) and shows them in the find window. But "Replace" can't replace them in the include files. So the replace doesn't run if everything is selected to be replaced.
I can understand why, I'm just letting you know for development sake.
Cheers Alex
Quote from: LordAdef on May 11, 2017, 09:03:47 PM"find" now finds key words in INCLUDE files (with Capital letters) and shows them in the find window. But "Replace" can't replace them in the include files.
Thanks, Alex. Version 12 May has a warning now, please let me know if that is the right choice. It would be technically possible to replace strings in the include files, but updating include files is not something I would support - too risky.
Among the other changes:
- By holding Ctrl and moving the mousewheel, the RichEdit control can zoom the display. At my age and my eyesight, I need 110%, but there may be people who have brilliant eyes and want to see more code. Pressing Alt Z saves the current zoom level; this is a global setting, i.e. RichMasm remembers this when opening
any document (it also affects the font in the Find listbox, but only after restarting RichMasm).
- introduced a new Event variable VKey2:
Event Key
Switch_ VKey2
Case_ VK_LEFT: wAddWin$ hMyEdit=" текст", 44 ; insert Unicode text at position 44
Case_ VK_RIGHT: AddWin$ hMyEdit=" missed", 50, 57 ; insert Ansi text at position 50, overwrite 7 bytes
Case_ VK_UP
Let My$=FileRead$("UnicodeIsEasy.asc")
wAddWin$ hMyEdit=My$
Case_ VK_DOWN: <wAddWin$ hMyEdit=wRec$(cfm$("\nВведите\nтекст\nздесь\n"))> ; append & use cfm$ for \n escapes
Endsw_Until now, VKey was available to test for e.g. VK_SPACE or whatever; and the rule was that a positive VKey comes from the main application, a negative one (.if VKey==-VK_SPACE) from the riched control. Now you can catch a keypress independently of whether the control has the focus or not. Full example attached.
The snippet above also demonstrates new optional arguments for AddWin$:
AddWin$ hRichEdit="Text" [, startpos][, endpos]
The online doc for AddWin$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1093) says it's normal edit controls only, but that is wrong. I should update that page...
QuoteThanks, Alex. Version 12 May has a warning now, please let me know if that is the right choice. It would be technically possible to replace strings in the include files, but updating include files is not something I would support - too risky.
ok JJ.
One other issue for you, still on the Find:
.Once I make a change in the include file and save it,
. come back to Main source code and
. search for something...
. the result in the Find is not updated for the include files, and still shows the old expression
Version 29 May is online (http://masm32.com/board/index.php?topic=94.0). As usual, you can just reinstall the package, no need to delete old files or backup your own sources.
Pens and brushes can now be created to arrays. This creates 100 random circles in random colours (attached):
include \masm32\MasmBasic\Res\MbGui.asm
Dim Pens() As DWORD
Dim Brushes() As DWORD
For_ ct=0 To 99
MakePen Pens(ct), Rand(-1), width 10 ; use random colours
MakeBrush Brushes(ct), Rand(-1) ; also for the fill
Next
MakePath 123, Circle(200) ; ID, type circle: radius 20%, i.e. n/1000 of window rect
Event Paint
For_ ct=0 To 99 ; ID pen/brush x y scaleX scaleY
GuiDraw 123, <Pens(ct)/Brushes(ct)>, <Rand(850).>, <Rand(850).>, eax, <Rand(900)> ; ScaleX is eax, same as scaleY
Next
GuiEndQuote from: LordAdef on May 13, 2017, 02:39:46 AMthe result in the Find is not updated for the include files, and still shows the old expression
Sorry, Alex, no time to fix that right now. You can reload, though: Shift F5
Good news: RichMasm works on Windows XP. Again. It had stopped working due to a hilarious Windows bug, see
Code pages and batch files - fun with XP (http://masm32.com/board/index.php?topic=6284.0).
As a side effect, I had to write a new macro:
include \masm32\MasmBasic\MasmBasic.inc
Init
Print Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
void MbWinVersion()
Print Str$(", build %i", dx)
EndOfCode
Rem returns major version in eax, minor version in ecx, and build in dxOutput: This is Windows version 6.1, build 7601
Note this is the
real Windows version, not what you declare via "compatibility settings".
Btw when building a project in RichMasm, the environment variable is accessible via
ifidn @Environ(oWin), <5>
MsgBox 0, "Built on XP", "Hi", MB_OK
endif
Drag an avi file over the exe, for example Mikl's demo file (https://yadi.sk/i/J4bVuX4H3JdByJ) - see Uncle Remus tales:#37a Animation (http://masm32.com/board/index.php?topic=6275.msg67228;topicseen#msg67228).
GuiParas equ "SysAnimate32 demo", w452, h374, bRgbCol(255, 255, 160)
include \masm32\MasmBasic\Res\MbGui.asm ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
GuiControl Avi, "SysAnimate32"
invoke SendMessage, hAvi, ACM_OPEN, 0, CL$()
invoke SendMessage, hAvi, ACM_PLAY, -1, 0FFFF0000h
GuiEnd
I was surprised how easy it is, but its usage is rather limited: no sound :(
Quote from: LordAdef on May 13, 2017, 02:39:46 AM. the result in the Find is not updated for the include files, and still shows the old expression
Implemented in version 31 May - please reinstall the whole package (http://masm32.com/board/index.php?topic=94.0), there was also a bug in the Ansi version of FileOpen$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1031).
Let me know if it's OK like that, Alex. In contrast to the current version, the "external" matches now respect also the "case" and "fw" checkboxes, i.e. case-sensitive and full word mode are working correctly for the include files now.
Quote from: jj2007 on May 31, 2017, 09:21:38 AM
Quote from: LordAdef on May 13, 2017, 02:39:46 AM. the result in the Find is not updated for the include files, and still shows the old expression
Implemented in version 31 May - please reinstall the whole package (http://masm32.com/board/index.php?topic=94.0), there was also a bug in the Ansi version of FileOpen$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1031).
Let me know if it's OK like that, Alex. In contrast to the current version, the "external" matches now respect also the "case" and "fw" checkboxes, i.e. case-sensitive and full word mode are working correctly for the include files now.
Great update Johen. I'm downloading it tonight when I get back home.
Version 13 June (http://masm32.com/board/index.php?topic=94.0) fixes an exotic bug in RichMasm - it choked if many uppercase INCLUDE files were found.
New feature: Console input with character limit as discussed here (http://masm32.com/board/index.php?topic=6315.0):
.Repeat
Print At(5, Locate(y)) " "
Let esi=Input$("Go ahead, edit that string: ", "123456789012345678", max20)
PrintLine " you typed [", esi, "]"
.Until Len(esi)<5
Attached is a beta, exe only, that plays media files. Drag an audio or video file over the exe, if the codec is installed it will play. Cursor left, space, cursor right are relevant keys. Hold Ctrl for fast forward, Shift for slow back+forth.
Minor update 11 July (download (http://masm32.com/board/index.php?topic=94.0)):
jd@150 equ KernelBase ; a little hack for a missing WinAPI,
j@VirtualProtectFromApp equ jbNextApi/150:s1111 ; may be refined in the near future
...
mov r12, rv(MessageBoxA, @address) ; address of MessageBoxA in the DLL
This is a rather exotic function needed for 64-bit code when you need the true address of a function in its DLL. Full example here (http://masm32.com/board/index.php?topic=6378.msg68416#msg68416).
Plus, RichMasm produces now better formatted output for this forum. (http://masm32.com/board/index.php?topic=5820.msg68375#msg68375)
Wow ! Such a wonderful project !
Would you recommend which debugger to use if MasmBasic dialect is used together with ML.exe ? (I mean, VS seems to provide a really decent and productive debugger for C/C++ or even MASM.)
Quote from: jiucenglou on July 15, 2017, 11:27:36 PM
Wow ! Such a wonderful project !
Would you recommend which debugger to use if MasmBasic dialect is used together with ML.exe ? (I mean, VS seems to provide a really decent and productive debugger for C/C++ or even MASM.)
Thanks ;-)
Re debugger, many of us here use Olly (http://www.ollydbg.de/version2.html).
Thank you for your recommendation very much ! I will try OllyDbg 2 :t
Yes... What a wonderful project. Extremely grateful for all the hard work and effort that has gone into developing this. Starting using the Rand function last week, but then I discovered Deb!, and it's been love at first site :)
Working with a lot of loops that involve the creation and use of indexed addressing. Can't recommend this function enough, especially the ability to output to a text file.
Keep up the good work :)
Thanks, Rob - that is the kind of feedback I've been looking for the last 20 years :greensml:
Re deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019): I rarely use deb 5 (to file) nowadays, but it can be useful. For monitoring a loop, try deb 7 or deb 30 - any number above 5 shows n times the result, then the loop continues. Also, deb 4, "The error:", eax, $Err$() is a very useful one in WinAPI programming ;-)
Cheers for the advice jj :)
deb 7 or 30 , I'll have to have a look. Excuse my ignorance , but these will require a Win32 console/window ? . Just had a quick read through the help file , but didn't see any info about these.
I'm using SDL2 , simply as a means of spitting out a custom texture , so I'm simply going into an Opengl/DirectX full screen mode. That's why I'm currently using the text file approach. Using the same approach to spit out any performance/benchmark info.
Cheers,
Rob
Quote from: Rob260z on August 01, 2017, 07:06:52 PMso I'm simply going into a full screen Opengl mode.
So that doesn't allow a separate console window, right? Then deb 5 is the only solution indeed. Or deb 0...3, you can cancel the messageboxes separately.
; OPT_Susy Console ; forces console mode
Well...I can actually make it run in a windowed mode. I'm going to explore this a little further. Has real potential.
Real-time debugging is going to be really beneficial, once I move past this initial setup phase.
Cheers for the info.
Quote from: Rob260z on August 01, 2017, 09:29:12 PMWell...I can actually make it run in a windowed mode. I'm going to explore this a little further. Has real potential.
Another trick:
winX=150
winW=900
ifidni @Environ(oSusy), <console> ; OxPT_Susy Console ; RichMasm autodetect will pick Windows, delete the x to force console
winX=450 ; leave more space for console output
winW=600
deb 4, "Hey, we are using a console in parallel to a window", $wc.lpszClassName
endif
invoke CreateWindowEx, WS_EX_ACCEPTFILES, wc.lpszClassName, chr$("Hello World"), ; set window title here
WS_OVERLAPPEDWINDOW or WS_VISIBLE,
winX, 150, winW, 400, ; window position: x, y, width, height
NULL, NULL, wc.hInstance, NULL
Please download and run the 26 August 2017 version of the package (http://masm32.com/board/index.php?topic=94.0). As always, you can just follow the instructions, the new installation does not change any of your sources or settings, does not write anything to the registry, and does not interfere with your Masm32 installation (I do reinstallations frequently myself when testing...).
Note that you can use an xmm reg as destination in QuadMath mode, but it has to be prefixed as MovVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1203) q:xmm0, "123", otherwise, an ordinary 64-bit integer will be loaded:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
include \masm32\MasmBasic\Res\QuadMath.inc
Init quad ; requires C:\TDM-GCC-32\bin\libquadmath-0.dll
mov esi, Chr$("1234567890123456789.0123456789012345678901234567890")
MovVal xmm0, esi
PrintLine "64-bit int: ", Tb$, Str$(xmm0)
MovVal f:xmm0, esi
PrintLine "double/Real8: ", Tb$, Str$(f:xmm0)
MovVal q:xmm0, esi
PrintLine "Quad float e:", Tb$, Quad$(xmm0)
MovVal q:xmm0, esi
PrintLine "Quad float g:", Tb$, Quad$(xmm0, "%*.33Qg") ; formats (https://gcc.gnu.org/onlinedocs/gcc-6.3.0/libquadmath/quadmath_005fsnprintf.htmlquadmath_005fsnprintf)
EndOfCode
Output:
64-bit int: 1234567890123456789
double/Real8: 1.23456789012346e+18
Quad float e: 1.23456789012345678901234567890123e+18
Quad float g: 1234567890123456789.01234567890123
The other aspect concerns UAsm (http://masm32.com/board/index.php?topic=6422.0): By default, RichMasm will from now on use the faster UAsm64 for building 32-bit as well as "dual" 64/32-bit (http://masm32.com/board/index.php?topic=5314.msg59884#msg59884) sources. If UAsm64 is not present in \Masm32\bin, RichMasm will ask you if you want to install it, and download and extract a recent version.
include \masm32\MasmBasic\MasmBasic.inc ; download version 6 September (http://masm32.com/board/index.php?topic=94.0)
Init
GetFiles \Masm32\examples\unicode_generic\*.asm|*.inc|*.rc ; use the "or" character to separate masks
For_ each ecx in Files$() : <PrintLine Str$("file %_i\t", ForNextCounter), ecx> ; one line is enough ;-)
EndOfCode
Output:file # 0 \Masm32\examples\unicode_generic\console\hello\hello.asm
file # 1 \Masm32\examples\unicode_generic\console\textio\textio.asm
file # 2 \Masm32\examples\unicode_generic\diskfile\diskfile.asm
file # 3 \Masm32\examples\unicode_generic\diskfile\WININC.INC
file # 4 \Masm32\examples\unicode_generic\multi_lingual\multi_lingual.asm
file # 5 \Masm32\examples\unicode_generic\multi_lingual\multi_lingual.inc
file # 6 \Masm32\examples\unicode_generic\multi_lingual\ansi.rc
file # 7 \Masm32\examples\unicode_generic\multi_lingual\rsrc - Copia.rc
file # 8 \Masm32\examples\unicode_generic\multi_lingual\rsrc.rc
file # 9 \Masm32\examples\unicode_generic\string_examples\append$\append$.asm
file #10 \Masm32\examples\unicode_generic\string_examples\cat$\cat$.asm
file #11 \Masm32\examples\unicode_generic\string_examples\find$\find$.asm
file #12 \Masm32\examples\unicode_generic\string_examples\switch$\switch$.asm
file #13 \Masm32\examples\unicode_generic\template\misc.asm
file #14 \Masm32\examples\unicode_generic\template\template.asm
file #15 \Masm32\examples\unicode_generic\template\template.inc
file #16 \Masm32\examples\unicode_generic\template\rsrc.rc
MasmBasic update 12 September: (http://masm32.com/board/index.php?topic=94.0)
- ifdeb allows single lines that create code only in debug mode:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
usedeb=1
For_ ecx=1 To 20
ifdeb push ecx : Print "[": .if 0
Print Str$("%_i ", ecx)
ifdeb .endif : PrintLine "]" : pop ecx
Next
EndOfCode
- RichMasm has got a more advanced "Obscure string" feature (more (http://masm32.com/board/index.php?topic=94.msg30979#msg30979))
- an error will be thrown if the handle for ToolTips is passed in esi
- finally, dynamic string arrays got a bit speedier, they are now practically as fast as fixed Dim some$(100) arrays:
include \masm32\MasmBasic\MasmBasic.inc
Init
PrintCpu 0
Dim MyArray$() ; create a dynamic array
NanoTimer() ; start high resolution timer
xor ecx, ecx
.Repeat
Let MyArray$(ecx) = Str$("This is string %i", ecx)
inc ecx
.Until ecx>=1000000
Print Str$("%i ms", NanoTimer(ms)), Str$(", %i Million strings allocated\n", MyArray$(?)/1000000)
Dim FixedArray$(1000000) ; create a fixed size array
NanoTimer()
For_ each ecx in FixedArray$(): <Let FixedArray$(ForNextCounter) = Str$("This is string %i", ForNextCounter)>
Inkey Str$("%i ms", NanoTimer(ms)), Str$(", %i Million strings allocated\n", FixedArray$(?)/1000000)
EndOfCode
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
353 ms, 1 Million strings allocated
349 ms, 1 Million strings allocated
Install the MasmBasic update 18 September 2017 (http://masm32.com/board/index.php?topic=94.0) to get this new feature inspired by the How to read Windows MFT thread (http://masm32.com/board/index.php?topic=6546.msg70196#msg70196):
include \masm32\MasmBasic\MasmBasic.inc
Init
Inkey "Dump of GetModuleHandle(0):", CrLf$, HexDump$(rv(GetModuleHandle, 0), 90h)
EndOfCode
Options are documented in MbGuide.rtf, as usual.
The other major change is that RichMasm got new menus (more (http://masm32.com/board/index.php?topic=6055.msg70165#msg70165)), thanks to LiaoMi :icon14:
Tested on WinXP, Win7-64 (also with Aero, see screenshot below) and Win10, looks OK so far, but let me know if it can be improved :icon_mrgreen:
Changes in version 26 October (http://masm32.com/board/index.php?topic=94.0):
- online help is updated, e.g. for deb & friends (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) (remember that in RichMasm, hovering over a keyword allows to access help with a right-click)
- see Graphics demo (http://masm32.com/board/index.php?topic=6631.msg71135#msg71135); handling of maps is strongly improved
- HexDump$() got a "dd" option:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=FileRead$("\Masm32\examples\exampl04\car\car.jpg") ; Masm32 SDK
PrintLine HexDump$(esi, 80) ; show 80 bytes of jpg header
Inkey HexDump$(esi, 80, dd) ; same but for use with code
EndOfCode
Output:006337D0 FF D8 FF E0 00 10 4A 46 49 46 00 01 00 01 00 64 ÿØÿà..JFIF.....d
006337E0 00 64 00 00 FF FE 00 1F 4C 45 41 44 20 54 65 63 .d..ÿþ..LEAD Tec
006337F0 68 6E 6F 6C 6F 67 69 65 73 20 49 6E 63 2E 20 56 hnologies Inc. V
00633800 31 2E 30 31 00 FF DB 00 84 00 08 05 06 07 06 05 1.01.ÿÛ.,,.......
00633810 08 07 06 07 09 08 08 09 0C 14 0D 0C 0B 0B 0C 19 ................
db 0FFh, 0D8h, 0FFh, 0E0h, 000h, 010h, 04Ah, 046h, 049h, 046h, 000h, 001h, 000h, 001h, 000h, 064h
db 000h, 064h, 000h, 000h, 0FFh, 0FEh, 000h, 01Fh, 04Ch, 045h, 041h, 044h, 020h, 054h, 065h, 063h
db 068h, 06Eh, 06Fh, 06Ch, 06Fh, 067h, 069h, 065h, 073h, 020h, 049h, 06Eh, 063h, 02Eh, 020h, 056h
db 031h, 02Eh, 030h, 031h, 000h, 0FFh, 0DBh, 000h, 084h, 000h, 008h, 005h, 006h, 007h, 006h, 005h
db 008h, 007h, 006h, 007h, 009h, 008h, 008h, 009h, 00Ch, 014h, 00Dh, 00Ch, 00Bh, 00Bh, 00Ch, 019h
- the new MasmBasic version is again compatible with UAsm
- a bug in RichMasm was fixed (if a very big document was loaded, and user opened a small one in the same instance, it crashed)
a) Version 29 October (http://masm32.com/board/index.php?topic=94.0) has now the "unique" feature for generation random numbers (->Unique random numbers (http://masm32.com/board/index.php?topic=6645.0)):
Rand(-99, 100, SomeIntegerArray(ecx), unique) ; min, max, destination, unique flag
Full example:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
tests=100
Dim SomeInteger() As DWORD
PrintLine Str$("Possible range: %i ... ", -tests/2), Str$(tests/2)
Let edi="unique numbers: "
Rand() ; set a seed value
For_ ecx=0 To tests-1
Rand(-tests/2, tests/2+1, SomeInteger(ecx), unique) ; min, max, destination, flag
Let esi=Str$(" %i ", SomeInteger(ecx))
.if Instr_(edi, esi)
inc ebx ; oops, we got that one already
.else
Let edi=edi+esi ; remember the last number
.endif
Next
if tests le 100
PrintLine edi ; show the unique numbers
endif
Inkey Str$("-- %i errors, hit any key --", ebx)
EndOfCode
Output:Possible range: -50 ... 50
unique numbers: -13 31 43 11 16 1 -14 -36 -6 21 34 -45 17 -2 -35 39 23 40 7 -1 -5 32 -25 -30 -28 -19 15 -26 0
-29 41 -10 27 -15 22 -33 44 35 -9 29 -12 -16 -24 13 -3 -38 26 -20 -21 20 4 18 -46 36 -23 47 37 49 -34 19 14
10 -37 9 -40 -49 -4 -32 -48 -27 -11 33 2 28 -17 -31 -39 -8 8 -41 -22 24 -50 38 25 -42 6 12 42 -47 48 -44 46
45 3 -7 -18 -43 50 30
-- 0 errors, hit any key --
If you find a duplicate, I owe you a beer, but you must come here to get it :bgrin:
Note that for high numbers of unique random numbers, e.g. tests=30000, it may take a few seconds.
b) another little feature: SetWin$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1092) can now set the text of child controls. Example:
include \masm32\MasmBasic\MasmBasic.inc
Init
Launch "Notepad.exe SetChildWin.rc", SW_RESTORE, 100 ; give Notepad a few milliseconds to set the caption properly
.if WinByTitle("SetChildWin.rc - ")
xchg eax, ecx ; set the handle to ecx (MasmBasic won't touch ecx)
SetWin$ ecx, 15=Replace$(Cat$(Win$(ecx, 15)), "Win$", "Win$#####", 0) ; replace with an easy-to-spot string
.endif
EndOfCode
Full project attached, tested with Win7-64 and WinXP. When you hit F6 in RichMasm, the fake rc file for Notepad gets generated from the text between the red Rsrc tags.
Version 8 November 2017 is ready to be installed. (http://masm32.com/board/index.php?topic=94.0) Changes:
- updated help file, with now 400+ macros documented (also online - use Ctrl F to find commands (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm); but remember the best help option is to use RichMasm, hover over a keyword like Open, then right-click on the word and copy the line that fits your case)
- fDate$() and fTime$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1267) can now take a third parameter to force any language:
include \masm32\MasmBasic\MasmBasic.inc
Init
Print "Right now, ", fDate$(0, "dddd dd MMMM yyyy "), fTime$(0, "HH:mm:ss"), Str$(", we are in ISO week %i\n", IsoWeek())
Print fDate$(0, "dddd dd MMMM yyyy ", russian), fTime$(0, "HH:mm"), Str$(", мы находимся в ИСО неделе %i", IsoWeek())
wMsgBox 0, wCat$(wfDate$(0, "dddd dd MMMM yyyy ", hindi)+wfTime$(0)), "This is Unicode:", MB_OK
EndOfCode
Output:
Right now, Wednesday 08 November 2017 04:55:26, we are in ISO week 45
среда 08 ноября 2017 04:55, мы находимся в ИСО неделе 45
- SetInt can now move the content of ST(0) to xmm0:
fldpi
Print Str$("PI=\t%Jf\n", ST(0))
fmul FP4(100.0)
SetInt ecx
Print Str$("100*PI=\t %i\n", ecx)
fldpi
fmul FP8(10.0e16)
SetInt xmm0
Print Str$("100*PI=\t %i\n", xmm0)
Output:
PI= 3.141592653589793238
100*PI= 314
10e16*PI=314159265358979324
- finally, the ternary operator If? can now also take the Zero? and Carry? flags as input (testbed attached):
xor ecx, ecx
Print Str$("zero flag set: %i\txor ecx, ecx\n", If?(zero?, 111, 222)) ; prints first number, 111
or ecx, -1
Print Str$("zero flag set: %i\tor ecx, -1\n", If?(zero?, 111, 222)) ; prints second number, 222
stc
Print Str$("carry set: %i\tstc\n", If?(Carry?, 111, 222)) ; carry is set, prints 111
clc
Print Str$("carry set: %i\tclc\n", If?(Carry?, 111, 222)) ; carry clear, prints 222
HexDump$() got new options:
Let My$=HexDump$("SomeFile.exe", file, dq) ; translate the file to a string ready for pasting
Attached source & exe of an application that translates any file into an include file. Limit is around 640kB for the *.inc file. The format is as follows (as an example, I translated \Masm32\MasmBasic\RichMasm.exe):.DATA
hdBytes=68608
RichMasmStart LABEL BYTE
.radix 16
dq 06172627261665A4D, 00000455068637375, 05A1809200001014C, 00000000000000000, 03202010B010F00E0, 000197A0000018400, 00000FE6800000000, 00000000C00001000
...
dq 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
.radix 10
.code
; FileWrite "RichMasm.tmp", offset RichMasmStart, hdBytes
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
.if Exist(CL$())
Let edi=HexDump$(Exist$, file, dq)
Let esi=Extract$(CL$(), "\", ".", xsRinstrL)+".inc"
Let ecx=Str$("%i bytes translated to ", LastFileSize)+esi+CrLf$+CrLf$+Left$(edi, 200)+\
CrLf$+"..."+CrLf$+Right$(edi, 200)+CrLf$+CrLf$+"Create inc (NO=copy to clipboard)?"
If_ Exist(esi) Then Let ecx="Attention, "+esi+" exists!!!!"+CrLf$+ecx
MsgBox 0, ecx, "File to *.inc:", MB_YESNOCANCEL or MB_ICONQUESTION
.if eax==IDYES
FileWrite esi, edi
.elseif eax==IDNO
SetClip$ edi
.endif
.else
If_ Rinstr(CL$(0), "\") Then inc eax
MsgBox 0, Cat$("Drag a file over "+eax), "File to *.inc:", MB_OK
.endif
EndOfCode
OPT_Arg1 \Masm32\MasmBasic\RichMasm.exe ; just for fun, translate the editor to .DATA ;-)
MasmBasic updated, please reinstall version 19 December 2017. (http://masm32.com/board/index.php?topic=94.0) Minor changes, inter alia:
- Cpu$():
include \masm32\MasmBasic\MasmBasic.inc
Init
MsgBox 0, Cat$("My CPU: "+Cpu$()), "Hi:", MB_OK
EndOfCode
NanoTimer() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1171) has been improved, see the new timings thread (http://masm32.com/board/index.php?topic=6718.msg71908#msg71908).
- Delay until (-> full example (http://masm32.com/board/index.php?topic=6483.msg72347#msg72347)):
Delay 1000 ; standard version: wait a second
PrintLine fTime$(0, "HH:mm:ss.fff"), Tb$, "started"
Delay until fTime$(s:1, "HH:mm:ss.123") ; use time$(current plus one second)
PrintLine fTime$(0, "HH:mm:ss.fff "), Tb$, NanoTimer$(), " restarted"
Rem - uses Sleep but preserves ecx
- the until variant uses a time string to wait until a precise moment; use e.g. fTime$(1, "HH:mm") to
suspend running until the current minute is finished; fTime$(s:10, ...) would mean 10 seconds
- the "controls" snippet in the templates has been improved (-> File/New Masm source/console/window/controls)
Let me know if there are any problems (there might be some with Windows XP - I test thoroughly for Win7 and Win10 but for XP I only have a VM).
MasmBasic 25 December 2017 (http://masm32.com/board/index.php?topic=94.0) features ClearFileCache for timings and benchmarks involving disk I/O (http://masm32.com/board/index.php?topic=6483.msg72680#msg72680), uMirror$() (http://masm32.com/board/index.php?topic=6483.msg72658#msg72658), plus a number of new controls. Here are 75 lines of code showing 18 controls in action (screenshot below, source & exe attached; drag a text file over the exe):
GuiParas equ "Controls", x660, y50, w500, h320, m4, b RgbCol(160, 255, 255) ; position, margins, background
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste ; define a menu (functions not implemented)
include \masm32\MasmBasic\Res\MbGui.asm
SetGlobals ticks=rv(GetTickCount), f$="some text to find", r$="Доброе утро!!!!" ; set global variables; note that they use ebx under the hood
SetGlobals ; initialise them
GuiControl ListBox, "listbox", x700, w300, h1000-80, WS_EX_CLIENTEDGE, +WS_BORDER or LBS_NOINTEGRALHEIGHT ; start at 70% width, use 30% width, full height; + means defstyle or ...
GuiControl MyDt, "syslink", "Date+Time (MSDN):", x700, w300, y1000-72, h0+18
GuiControl MyTime, "time", x700, w300, y1000-53, h0+25
GuiControl MyDate, "date", x700, w300, y1000-26, h0+25
GuiGroup "Controls can be grouped:", w0+246, h0+75, bgcol RgbCol(255, 255, 200)
GuiControl StatFind, "static", "Find:", h0+22, w0+55 ; general syntax:
GuiControl StatRepl, "static", "Replace:", h0+22, w0+55, y 0+24 ; guicontrol ID, "class", args "text", x, y, w, h, style
GuiControl EditFind, "edit", f$, x 0+62, w0+100, h0+22, WS_EX_CLIENTEDGE ; args have a variable part plus an optional fixed one, example:
GuiControl EditRepl, "edit", r$, x 0+62, w0+100, h0+22, WS_EX_CLIENTEDGE, y 0+28 ; x1000-90 means "at right border, i.e. 100.0%, minus 90 pixels"
GuiControl Cis, "button", BS_AUTOCHECKBOX, h0+22, x0+170, w0+60, "Case" ; args may appear in no particular order, e.g. "Case" at the end
GuiControl Fw, "button", text "Full word", h0+22, x0+170, w0+64, y0+28, BS_AUTOCHECKBOX
GuiGroup end
GuiControl BigEdit, "richedit", y0+120, h1000-120, w700 ; y at fixed 120px, h at full height minus 100px; width 70.0%
If_ Exist(CL$()) Then <SetWin$ hBigEdit=FileRead$(Exist$)> ; OPT_Arg1 \Masm32\MasmBasic\Res\MbSnippets.asc
GuiControl Ok, "button", "Reset", x0+257, w0+80, h0+24, BS_DEFPUSHBUTTON
GuiControl Progress, "progressbar", y0+88, h0+29, w700 ; , style PBS_SMOOTH ; no effect if manifest is active
GuiControl Status, "statusbar", "MasmBasic is pure assembly!!!!"
GuiControl TimeMs, "static", x0+260, y0+32, h0+17, w0+75
GuiControl InstallMB, "syslink", x0+260, y0+50, h0+17, w0+80, "MasmBasic" ; RichMasm: copy a URL, select a word, press Ctrl K
GuiControl Track, "trackbar", x0+257, y0+68, h0+17, w0+75, style TBS_AUTOTICKS or TBS_ENABLESELRANGE
StringToArray cfm$("These\nare\nsome\nentries\nin\na\nlittle\nlistbox"), lbox$() ; create an array (use Recall to load a textfile)
SetListbox lbox$() ; fill the listbox
Event Timer
sub rv(GetTickCount), ticks
invoke SendMessage, hProgress, PBM_SETPOS, eax, 0
SetWin$ hTimeMs=fTime$(0, "HH:mm:ss.fff") ; shows milliseconds (check CPU usage in Task Manager!)
Event Message
.if uMsg_==WM_HSCROLL ; horizontal trackbar sends this message
mov eax, lParam_
.if eax==hTrack
mov ticks, rv(GetTickCount) ; try to sync with progressbar ;-)
shl rv(SendMessage, lParam_, TBM_GETPOS, 0, 0), 9
sub ticks, eax
.endif
.elseif uMsg==WM_CLOSE
if 0 ; put 0 for testing (Escape quits), 1 for the release version
MsgBox 0, "Save settings?", "Hi", MB_YESNOCANCEL
sub eax, IDCANCEL
je @RetEax ; return 0, i.e. do NOT close
.if eax==IDYES-IDCANCEL
MsgBox 0, "Add your 'save settings' etc here", "Hi", MB_OK
.endif
endif
.endif
Event Key
.if VKey==VK_A
MsgBox 0, "You pressed 'A'", "Hi", MB_OK ; negative VK_ codes indicate the key was hit in an edit control
.endif
Event Command
Switch_ MenuID ; menu entries start with 0, controls return their IDs here
Case_ 0, Ok
SetWin$ hStatus="You clicked the Open menu or the Reset button"
mov ticks, rv(GetTickCount)
Case_ 1: call MySave ; your own functions may appear after EndOfEvents
Case_ 2: invoke SendMessage, hWnd, WM_CLOSE, 0, 0 ; the Exit menu entry
Case_ 3 .. 9 : <MsgBox 0, Str$("You clicked MenuID #%i", MenuID), "Menu clicked:", MB_OK>
Case_ EditFind, EditRepl, Cis, Fw
wSetWin$ hStatus=wStr$("You clicked inside the group on item %i with text '", MenuID)+wWin$(rv(GetDlgItem, hWnd, MenuID))+"'" ; Unicode is possible
Endsw_
.if NotifyCode==DTN_DATETIMECHANGE && (wParam==MyDate || wParam==MyTime)
SetWin$ hStatus=Cat$(Win$(hMyDate)+", "+Win$(hMyTime)) ; 11.12.2013, 12:34:56
.endif
If_ NotifyCode==NM_CLICK && (word ptr wParam==InstallMB || word ptr wParam==MyDt) Then <wShEx Link$()> ; open a web page
If_ NotifyCode==LBN_SELCHANGE && word ptr wParam==ListBox Then SetWin$ hStatus=LbSel$ ; LbSel$ returns the text of the current listbox entry
EndOfEvents
MySave proc ; your procs go below EndOfEvents
SetWin$ hStatus="You clicked the Save menu"
ret
MySave endp
GuiEnd
P.S.: You may try other types of controls, see Current UI Automation Control Types (https://msdn.microsoft.com/en-us/ee671197%28v=vs.85%29#currentcontroltypes) for an overview. Let me know what you tried and if it worked; if not, I may be able to implement the missing bits. Btw there is no "control" that allows to pick colours. Instead, use the MasmBasic RgbCol (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1331) macro with ?, for example: invoke someapi, RgbCol(?). Just for fun, here an "add-on" for the source above: SetWin$ hStatus="You clicked the Open menu or the Reset button"
mov ticks, rv(GetTickCount)
invoke DeleteObject, hcGroupBx ; internal handles for the groupbox (not documented)
mov hcGroupBx[4], RgbCol(?)
mov hcGroupBx, rv(CreateSolidBrush, eax)
invoke InvalidateRect, hcGroupBx[8], 0, 1
hi jj2007
I installed the masm32 sdk without problems but trying to install MasmBasic trows Wndows Defender into panic, I forgot the trojans name that it purportedly found, any advise?
Just tested the current package on Jotti, details here (https://virusscan.jotti.org/en-US/filescanjob/wimbb8ufl1), but "0/18 scanners reported malware". Quite unusual, actually :icon_mrgreen:
Similar for VirusTotal (results (https://www.virustotal.com/#/file/efd1fbb01c14902ba1c974a8c74849f82572402dd8949aba9295e7a233acf63f/detection)) - the Baidu AV reported "WisdomEyes", whatever that is, but 60 others say it's clean.
The Forum is on a safe server, and the MasmBasic package gets built with an automated procedure. There is no chance of a trojan creeping in. But many AV produce false positives - we even have a dedicated sub-forum AV Software sh*t list (http://masm32.com/board/index.php?board=23.0) :bgrin:
Assembler produces by its nature suspicious code: The virus scanners expect C/C++ initialisation routines, CRT, SEH, etc; if they don't find them, they shout foul. Sometimes they shout foul because they see a pushad ... popad sequence, which is very unusual in C code, so it's "suspicious". Everything that is non-standard looks dangerous to them. Well, we are all proud here to produce non-standard software, so evidently there is a certain tension between assembler programmers and the AV brigade. And to be honest, there is also a community of assembler programmers who do produce malware, but we usually smell them from a distance if they appear here and ask for advice. The forum rules are very strict, and for valid reasons.
If you cannot ignore or override the message, try if there is an option to exclude certain folders, e.g. \Masm32\, from the scan. In the last five ten years or so, we had one case of a virus introduced here in this forum by a young member (who apparently had an infected machine without knowing it), and it was spotted by experienced members, not by their antivirus software...
ok thanks, I suspected it was a false positive.
Just remembered the Test your AV software (http://masm32.com/board/index.php?topic=4814.0) thread, which I launched two years ago because I couldn't explain why Windows Defender never tried to defend me from really suspicious software ;)
Sometimes you may want to know in which line of a string array a certain text is found. The standard way of doing this is a loop: or ecx, -1
.Repeat
inc ecx
.Until Instr_(L$(ecx), Match$, 2) || ecx>ebx
Attached is a new MatchLine(L$(), "text", mode) macro that does the same but a factor 9*) faster:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
include MatchLine.mac ; the new macro
Init
PrintCpu 0
Match$ equ <"duplicate include"> ; see Windows.inc, line 26900: echo WARNING Duplicate include file windows.inc
Recall "\Masm32\include\Windows.inc", L$()
xchg eax, ebx
PrintLine "new fast MatchLine:"
push 9 ; ten iterations
.Repeat
NanoTimer()
PrintLine Str$("Match in line %i found in ", MatchLine(L$(), Match$, 2)), NanoTimer$()
dec stack
.Until Sign?
PrintLine cfm$("\nold loop method:")
push 9 ; ten iterations
.Repeat
NanoTimer()
or ecx, -1
.Repeat
inc ecx
.Until Instr_(L$(ecx), Match$, 2) || ecx>ebx
PrintLine Str$("Match in line %i found in ", ecx), NanoTimer$()
dec stack
.Until Sign?
EndOfCode
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
new fast MatchLine:
Match in line 26899 found in 215 µs
Match in line 26899 found in 205 µs
Match in line 26899 found in 204 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 203 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs
old loop method:
Match in line 26899 found in 1742 µs
Match in line 26899 found in 1753 µs
Match in line 26899 found in 1831 µs
Match in line 26899 found in 1774 µs
Match in line 26899 found in 1728 µs
Match in line 26899 found in 1721 µs
Match in line 26899 found in 1722 µs
Match in line 26899 found in 1722 µs
Match in line 26899 found in 2017 µs
Match in line 26899 found in 1740 µs
Usage of MatchLine() is restricted to:
- unmodified text arrays obtained with Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172)
- Instr_ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153) modes 0 (=case-sensitive) and 2 (=intellisense, case of first char ignored)
*)
MatchLine() is about 9x as fast as the loop method for a small file like Windows.inc - and it is probably irrelevant if the search takes 0.2 or 1.8 milliseconds. My tests with a much bigger file, 12MB and 164,000 lines (i.e. too big to be cached) still show a factor 4 improvement.
Macro and exe are attached - grateful for some timings on other CPUs.
There is a bug in the Dim directive. It uses a call to HeapAlloc with NULL as the heap which leads to crash.
Quote from: 2B||!2B on April 17, 2018, 09:47:41 PM
There is a bug in the Dim directive. It uses a call to HeapAlloc with NULL as the heap which leads to crash.
Can you post your code please? Since I use Dim
very often, and without such problems, I suspect that you forgot to use Init at the beginning. I am afraid the documentation is a bit misleading there - Init is not optional, some commands will simply not work. Sorry for that, it will be corrected once I find time to post a new version.
Quote from: jj2007 on April 17, 2018, 10:17:22 PM
Quote from: 2B||!2B on April 17, 2018, 09:47:41 PM
There is a bug in the Dim directive. It uses a call to HeapAlloc with NULL as the heap which leads to crash.
Can you post your code please? Since I use Dim very often, and without such problems, I suspect that you forgot to use Init at the beginning. I am afraid the documentation is a bit misleading there - Init is not optional, some commands will simply not work. Sorry for that, it will be corrected once I find time to post a new version.
Hi man,
Yes you are right. Have forgot the Init actually sorry about that.
Added it before Dim and now it works fine.
Awesome work man.
I have a question. Why do you use FPU/MMX/SSE instructions set so often? are there any advantages by using them rather than using the standard x86 instructions set? like faster execution, smaller code size maybe?
There are no MMX instructions in MasmBasic (MMX code is inefficient, and there are conflicts with the FPU).
For calculations, the FPU is generally being used; it's not faster (and not slower) than the corresponding SSE* instructions, but internally it gives REAL10 precision, while SSE* offers only double precision, i.e. REAL8.
SSE* code is generally not shorter than ordinary x86 (but there are exceptions). However, it's often a lot faster. Take a simple example, getting the length of a zero-delimited string. There is a little thread here (http://www.masmforum.com/board/index.php?topic=14626.0) showing how the Masm32 team developed the current MasmBasic Len() macro. The thread has 149 replies, meaning it took a while to find the fastest option. Check yourself how fast it is, compared to the strlen function of the C runtime library (remember C is the fastest language on Earth :P):
include \masm32\MasmBasic\MasmBasic.inc
Init
Recall "\Masm32\include\Windows.inc", L$() ; get a string array
push eax ; #elements
xor ebx, ebx
xor edi, edi
NanoTimer()
.Repeat
invoke crt_strlen, L$(ebx)
add edi, eax ; calculate total len
inc ebx
.Until ebx>=stack
Print "The CRT needs ", NanoTimer$(), Str$(" for calculating the length of %i strings", ebx), Str$(", a total of %i bytes\n", edi)
xor ebx, ebx
xor edi, edi
NanoTimer()
.Repeat
add edi, Len(L$(ebx)) ; calculate total len
inc ebx
.Until ebx>=stack
pop edx
Inkey " MB Len needs ", NanoTimer$(), Str$(" for calculating the length of %i strings", ebx), Str$(", a total of %i bytes\n", edi)
EndOfCode
Note that Windows.inc has relatively short strings. The difference between the speed of Len vs crt_strlen is much bigger for long strings. For example, if you apply the code above to a bible.txt file, with longer strings, the difference is twice as much. I won't tell you how much because there a C/C++ coders here in the forum, and they might fall into a deep depression if they see the results :icon_cool:
Attached a full example, comparing also the Instr() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153) performances of MasmBasic and the CRT (if that sounds interesting, see Benchmark 2: Alice in Wonderland (http://old.blog.phusion.nl/2010/12/06/efficient-substring-searching/) for a CRT strstr vs Boyer-Moore comparison)
Ah ok i got it now thanks for clarifying that. Actually i used some FPU instructions for floating point result (like progress bar 0.# for example) but have never used SSE instructions. :biggrin:
Quote from: jj2007 on April 19, 2018, 05:32:39 PM
I won't tell you how much because there a C/C++ coders here in the forum, and they might fall into a deep depression if they see the results :icon_cool:
Lol, they can still use inline ASM though :biggrin:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals MyR4:REAL4, MyW:WORD=-123, MyDw:DWORD=-123
Init
PrintLine cfm$("number\tFloor(number)\tCeil(number)")
PrintLine Str$("%4f", MyW), Str$("\t%5f", Floor(MyW)v), Str$(" \t%5f", Ceil(MyW)v), " (WORD size integer)"
PrintLine Str$("%4f", MyDw), Str$("\t%5f", Floor(MyDw)v), Str$(" \t%5f", Ceil(MyDw)v), " (DWORD size integer)"
For_ ecx=0 To 29
Rand(-99.9, +99.9, MyR4)
PrintLine Str$("%4f ", MyR4), Str$("\t%5f", Floor(MyR4)v), Str$(" \t%5f", Ceil(MyR4)v)
Next
EndOfCode
Output:number Floor(number) Ceil(number)
-123.0 -123.00 -123.00 (WORD size integer)
-123.0 -123.00 -123.00 (DWORD size integer)
-9.629 -10.0000 -9.0000
-85.50 -86.000 -85.000
-72.59 -73.000 -72.000
72.67 72.000 73.000
31.14 31.000 32.000
64.07 64.000 65.000
-55.86 -56.000 -55.000
57.42 57.000 58.000
-95.26 -96.000 -95.000
3.386 3.0000 4.0000
12.49 12.000 13.000
-27.00 -28.000 -27.000
15.36 15.000 16.000
35.19 35.000 36.000
-49.67 -50.000 -49.000
-70.70 -71.000 -70.000
17.82 17.000 18.000
-7.807 -8.0000 -7.0000
37.56 37.000 38.000
95.73 95.000 96.000
27.80 27.000 28.000
-67.03 -68.000 -67.000
68.09 68.000 69.000
-75.14 -76.000 -75.000
-53.27 -54.000 -53.000
55.16 55.000 56.000
75.63 75.000 76.000
90.65 90.000 91.000
88.01 88.000 89.000
-21.09 -22.000 -21.000
Not included in the current (December '17) release, therefore attached as FloorCeil.inc; you may add it to your MasmBasic.inc.
Note the red v after the Str$("format", Numberv): Floor() and Ceil() always return ST(0) for further processing; if you just print the value, it needs to be popped via fstp st from the FPU. That's what the v does. Of course, you can also pop it directly into another variable, specified as second argument:
Floor(123.456, MyDw)
Print Str$("dw(123.456)=%i", MyDw)
The first argument can be an immediate (interpreted as double) or a DWORD, WORD, REAL4 ... REAL10 variable.
The second example in the MasmBasic guide fails to assemble due to missing DualWin.inc file. I see LibUsed$() example is also using JBasic.inc instead of MasmBasic.inc. MasmBasic Version 25 Dec 2017.
Thanks for the feedback. Did you get any error messages?
Please tell me if the following files are present (this helps me to understand what went wrong):
\Masm32\MasmBasic\Res\GetPT.exe
\Masm32\MasmBasic\Res\StructInfo.txt
- Extract the attached files to \Masm32\MasmBasic\Res
- Try again to build the example; if that doesn't work, try to run \Masm32\MasmBasic\Res\GetPT.bat
Note that the 64-bit examples build also with MASM; to do so, add an OPTion as follows:
include \masm32\MasmBasic\Res\JBasic.inc ; OPT_Assembler ML
However, RichMasm prefers UAsm and will try to install it if it's not present at \Masm32\bin\Uasm64.exe
You can do that manually, too: install UAsm64 (http://www.terraspace.co.uk/uasm.html#p2), i.e. extract \Masm32\bin\Uasm64.exe
Let me know if it works, please.
Hi jj,
Is there a Unicode Split$() version?
No, but it could be implemented. Something like this works already - not Unicode but Utf8:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="Введите\nтекст\nздесь"
For_ ct=0 To Split$(esi, "\n", My$())-1
PrintLine "[", My$(ct), "]"
Next
EndOfCode
Output:
[Введите]
[текст]
[здесь]
What exactly do you want to do?
Cool, but i don't want to assign my string to a new variable. My string is like "####STRING####STRING" etc
So i use #### as string delimiter.
But i used wInstr and it worked fine for me. Although i have to add a null terminator after each substring, this way i can use the string in it's source.
Quote from: jj2007 on October 25, 2018, 11:07:41 AM
Thanks for the feedback. Did you get any error messages?
*** Assemble using \masm32\bin\UAsm64 /c /coff /Zd /Zi /Zf tmp_file.asm ***
UASM v2.46, Dec 8 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
*** using Res\JBasic32.lib ***
\masm32\MasmBasic\Res\JBasic.inc(558) : Error A2106: Cannot open file: "\Masm32\MasmBasic\Res\DualWin.inc" [ENOENT]
\masm32\MasmBasic\Res\JBasic.inc(558): Included by
Tmp_File.asm(1): Main line
Quote
Please tell me if the following files are present (this helps me to understand what went wrong):
\Masm32\MasmBasic\Res\GetPT.exe
\Masm32\MasmBasic\Res\StructInfo.txt
GetPT.asm exists, but not GetPT.exe.
StructInfo.txt exists.
Quote
- Extract the attached files to \Masm32\MasmBasic\Res
Extracted the files and ran GetPT.exe in a command prompt. Had to turn off security.
The example (32-bit) assembled and ran.
I re-enabled security and now the file names \masm32\masmbasic\mbguide.exe and \masm32\masmbasic\tmp_file.exe are flagged as suspicious. polink can't create them - access denied.
I can probably create the exe files in another directory, but that means i'll have to use a custom BAT file for each example.
*** Assemble using \masm32\bin\UAsm64 /c /coff /Zd /Zi /Zf tmp_file.asm ***
UASM v2.46, Dec 8 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
*** MasmBasic version 25.12.2017 ***
Tmp_File.asm: 6 lines, 2 passes, 99 ms, 0 warnings, 0 errors
*** Link MbGuide.obj rsrc.res using polink, sub Console /debug /mapinfo:lines***
Writing debug information
Compacting CodeView information
POLINK: fatal error: Access is denied.
*** Link error ***
So it's all a security thing. If I used an AV, I would simply exclude the whole \Masm32 folder. Assembly code is considered unsafe because it's unusual by the dumb AV brigade, see our dedicated sub-forum AV Software sh*t list (http://masm32.com/board/index.php?board=23.0) 8)
It has been a while since MasmBasic was updated - grab the new version here (http://masm32.com/board/index.php?topic=94.0). Below an alphabetical list of the new macros added. In RichMasm, check File/MasmBasic help for the new keywords. Let me know if one is missing.
AddMru MACRO pTxt
ArrayStripDuplicates MACRO numID
Ceil MACRO arg, dest
ClosePipe MACRO arg:=<2>
ExeFromExt$ MACRO argExt, opt:=<2>
Floor MACRO arg, dest
Geo$ MACRO arg1:=<GEO_FRIENDLYNAME>, arg2:=<G
HeapStrings MACRO
LineInput MACRO dest$
Lset MACRO args:VARARG
MruText$ MACRO arg
MulQQ MACRO argQ1, argQ2, pDest
rCosinus MACRO arg
ResFile$ MACRO id
rSinus MACRO arg
SetAxisX MACRO args:VARARG
SetAxisY MACRO args:VARARG
SetMru MACRO fname ; SetMru "filename.ini"
SetRgbCol MACRO dest, noarg
ShowPlaces MACRO arg:=<1>
StoreHeader MACRO pSHeader
TitleCase$ MACRO arg
uClip$ MACRO MbLimit
uFileOpen$ MACRO args:VARARG
uFileSave$ MACRO args:VARARG
uSetWin$ MACRO arg1:REQ
uWin$ MACRO h1, cHandle
wExeFromExt$ MACRO argExt, opt:=<2>
wGeo$ MACRO arg1:=<GEO_FRIENDLYNAME>, arg2:=<
Win64 MACRO
Hi jj,
I could not get the Try/Catch to work.
Init tc
Is causing unresolved external symbol.
error LNK2001: unresolved external symbol _MbTryCatch@0
fatal error LNK1120: 1 unresolved externals
How do i solve it?
Without seeing your full code, I can't help you much. This works:
include \masm32\MasmBasic\MasmBasic.inc ; simple Try/Catch demo - use as a template
Init tc ; initialise MasmBasic with Try/Catch (aka SEH)
PrintLine "This code was built with ", @AsmUsed$()
mov eax, 123 ; use 123 as the dividend
cdq ; and sign-extend it to edx
xor ecx, ecx
Try
div ecx
PrintLine "Congrats, it worked!!!!" ; you won't see this line
Catch
PrintLine "Sorry, div ecx failed"
Finally
PrintLine Str$("Ouch, we had an exception in source line %i at\nAddress\t", LastEx(line)), Hex$(LastEx(addr)), CrLf$, "Code", Tb$, Hex$(LastEx(code)), CrLf$
Inkey "The OS reports:", CrLf$, LastEx(info)
EndOfCode
OPT_TryCatch on ; tells MasmBasic's preferred editor RichMasm to select the source line that triggered the first exception
This code was built with UAsm64
Sorry, div ecx failed
Ouch, we had an exception in source line -6 at
Address 004010D4
Code C0000094
The OS reports:
{ERRORE DI EXCEPTION}
Divisione intera per zero.
EIP 004010D4
Code C0000094
The code you posted does not compile if used inside a procedure
Error A2093: Cannot nest procedures
Error A2142: Unmatched block nesting: MbTryCatch
Try/Catch does not work inside a procedure. I tried using it outside a procedure and it compiled.
Is there a way to fix this so it can be used inside a procedure?
I cannot diagnose what went wrong if you don't post the complete code. This works fine:
include \masm32\MasmBasic\MasmBasic.inc ; simple Try/Catch demo - use as a template
Init tc, console ; initialise MasmBasic with Try/Catch (aka SEH), and output errors to console
PrintLine "This code was built with ", @AsmUsed$()
call MyTest
Exit
MyTest proc
mov eax, 123 ; now we'll do something illegal in line 13...
cdq
xor ecx, ecx
Try
; ****** the line below will be selected a second after the program finishes: ******
div ecx ; dividing by zero is a criminal act, right?
Print Str$("div succeeded, eax is %i\n", eax) ; you will not see this message
Catch
Print Str$("div failed, eax is still %i\n\n", eax)
PrintLine Str$("Ouch, we had an exception in source line %i at\nAddress\t", LastEx(line)), Hex$(LastEx(addr)), CrLf$, "Code", Tb$, Hex$(LastEx(code)), CrLf$
PrintLine "The OS reports:", CrLf$, LastEx(info)
Finally
ret
MyTest endp
EndOfCode ; OPT_TryCatch on ; activate jump to the error line in the source code
Output:
This code was built with UAsm64
div failed, eax is still 123
Ouch, we had an exception in source line 13 at
Address 0040110A
Code C0000094
The OS reports:
{ERRORE DI EXCEPTION}
Divisione intera per zero.
EIP 0040110A
Code C0000094
Which code you want me to post?
I have only tried to compile your code that you posted earlier.
So does the Init TC needed to be called outside a procedure?
and also, do we need to call it once in every thread?
Quote from: 2B||!2B on November 29, 2018, 01:11:24 PM
Which code you want me to post?
Your complete code. My crystal ball is not working today, I must see what you are trying to assemble...
Quote from: jj2007 on November 25, 2018, 12:48:54 PM
It has been a while..
- could not open MenusRM.ini
- problem with @AsmUsed$()
Quote from: HSE on November 30, 2018, 03:16:20 AM- could not open MenusRM.ini
- problem with @AsmUsed$()
Both problems fixed, please reinstall MasmBasic (http://masm32.com/board/index.php?topic=94.0). Grateful if you could test this snippet with the new version:
GuiParas equ "Hello World", w160, h100
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyEdit, "RichEdit", Cat$("This program was assembled with "+@AsmUsed$()+" and uses common controls version "+ComCtl32$())
GuiEnd xp
Hi
I get this popping up when I try to run the program. It's not from the AV software (Avast).
I'm running Windows 7.
Sorry, can't figure out how to upload images.
Many thanks
-Ian
Hi Ian,
RichMasm.exe is the editor, and I use it all the time on several machines. It is clean, no virus there, I know it because I build it from the source, over 20,000 lines. However, several AV scanners report malware, see the VirusTotal results (https://www.virustotal.com/#/file/0b674d9888d10af2eb32d0f9843a1f680d15230a92a2813c0a3cdf9ba06f6ded/detection): 18 out of 70! Here is the report for the same file but uncompressed (https://www.virustotal.com/#/file/09e4a8f78506e6eeb109d62ef26817db79d2032a60e9d2f9a9f58b5db101c152/detection), and the detection rate drops to 6 of 69. So simple compression is sufficient for 12 of these brilliant AV engines to shout foul. The reason is that no AV can test for all viruses and trojans in the wild, the databases would be huge, and testing would slow down your Windows to a crawl. So they use "heuristics" for detecting "suspicious behaviour", such as: Does the instruction "pushad" appear in the exe? Normal for assembler, almost never used by C compilers.
Check what the better AV engines report, like Kaspersky, Symantec etc., and then decide whether you really want to learn assembly. Once your executables grow a bit in size, they will never look like mainstream C/C++ executables - bad luck :P
I see you are using Avast. Virustotal says Avast reports Win32:Evo-gen, and googling for that virus leads quickly to
Is Win32.Evo-gen(Susp) a False Positive? (https://forum.avast.com/index.php?topic=173072.0) and What's with all the new Win32:Evo-gen [Susp] false positives? (Read 23100 times) (https://forum.avast.com/index.php?topic=151077.0), so RichMasm.exe is not the only victim of Avast.
If you are interested, the forum has a dedicated section "AV Software sh*t list" (http://masm32.com/board/index.php?board=23.0).
Cheers, Jochen
P.S.: VirusTotal has "Details" and "Behaviour" tabs. Here are details for the attached uncompressed RichMasm.exe (https://www.virustotal.com/#/file/09e4a8f78506e6eeb109d62ef26817db79d2032a60e9d2f9a9f58b5db101c152/details):
Win32 Executable MS Visual C++ 4.x (59.6%)
Win32 Executable MS Visual C++ (generic) (13.8%)
Win64 Executable (generic) (12.2%)
Windows screen saver (5.8%)
Win32 Dynamic Link Library (generic) (2.9%)
So they believe with 59.6+13.8%=73.4% probability that it was built with MS Visual Crap :icon_mrgreen:
Here is another example (https://www.virustotal.com/#/file/8da5e5241fa1d1f50c5a6bb63d6da9f02cb1c56cf115e11e87098369f0b0852c/details), it is the Download URL with UTF8 (http://masm32.com/board/index.php?topic=6483.msg83157#msg83157) executable:
Win64 Executable (generic) (47.7%)
Windows screen saver (22.6%)
Win32 Dynamic Link Library (generic) (11.3%)
Win32 Executable (generic) (7.7%)
OS/2 Executable (generic) (3.5%)
So they believe it's a Win64 exe. Or a DLL, or maybe a screensaver. Oh well, this is hitech, folks :t
I attach the uncompressed version of RichMasm.exe - welcome to the Forum :icon14:
nice info :icon14:
Please reinstall MasmBasic, updated on 25 January 2019. (http://masm32.com/board/index.php?topic=94.0)
Minor improvements under the hood, plus:
1. A new macro, _Local; my old favourite programming language, GfaBasic, had local variables (of course), but in contrast to MASM one could initialise them. This is now possible in Assembler:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
.code
MyTest proc uses esi edi ebx arg1, arg2
LOCAL var1, var2, rc:RECT, buffer[100]:BYTE ; "normal" locals, will be initialised to zero
_Local MyR4:REAL4=12345.6789, MyR8:REAL8=1234567890.1234567890 ; REAL variables
_Local var3=arg2, var4=200, x$=arg1, y$="Hello World" ; DWORDs and strings
ClearLocals ; clear or set locals
Print Str$("v1=%i", var1), Str$(", v2=%i", var2), Str$(", v3=%i", var3), Str$(", v4=%i", var4), Str$(", a2=%i", arg2)
Print Str$(", R4=%7f", MyR4), Str$(", R8=%Df", MyR8)
PrintLine ", x$=", x$, ", y$=", y$
ret
MyTest endp
Init
For_ ecx=0 To 150
invoke MyTest, Str$(ecx), ecx
Next
EndOfCode
The syntax is _Local var=whatever (i.e. understroke plus camel case Local). The declarations must be followed by ClearLocals. Full project is attached.
2. NoTag$() recognises many more special characters now. Test it:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=FileRead$("http://masm32.com/board/index.php?topic=94.0") ; assign page to a string
FileWrite "temp.txt", NoTag$(esi) ; strip the tags and write plain text to disk
ShEx "temp.txt" ; have a look with ShellExecute
EndOfCode
3. A bugfix for the SysLink GuiControl; the tooltips didn't appear. Now it's working fine, see attached project and screenshot below.
as always JJ love your hard work on masmbasic
Thanks, anunitu :icon14:
you sly asm devil
Update 31 January 2019 (http://masm32.com/board/index.php?topic=94.0):
- Rand(): randomness of REAL8 variables improved
- add2m and sub2m macros (use like m2m)
- MakePath: graphs can now be modified 'on the fly', e.g. in the Timer event, thus allowing moving shapes (demo attached):
MakePen hPenBez, RgbCol(255, 255, 0, 0), width 4
ArraySet pts() As DWORD = 10, 10, 80, 40, 40, 190, 190, 50, 100, 170, 180, 170, 100, 0
MakePath 123, Bezier(pts())
Event Timer
add2m pts(2), dirX
add2m pts(7), dirY
Event Paint
GuiDraw 123, hPenBez, 10.0, 10.0, 2500, 5000 ; x, y, scaleX, scaleY
The MasmBasic update of 5 February 2019 (http://masm32.com/board/index.php?topic=94.0) features a new ArrayIndex() macro inspired by Guga's Fast Compare Real8 with SSE (http://masm32.com/board/index.php?topic=7659.0) thread. The macro returns in eax the position of a number in a sorted array; if dl is zero, an exact match was found, otherwise the nearest position will be returned in eax. Syntax example:
Print Str$("The position of the number 8377 in the array table() is %i", ArrayIndex(table(), 83777))
The sorted array, table() in this example, can be composed of DWORD, QWORD or REAL8 values. Below and attached a complete example:
include \masm32\MasmBasic\MasmBasic.inc
Init
StringToArray FileRead$(99), table() As DWORD ; read an array from resource #99
ArraySort table() ; sort ascending
Let esi="83777" ; just a suggestion
Print "Hit Escape & Return to exit"
.While 1
Print At(0, 1)
Let esi=Input$("Gimme a prime: ", esi)
.Break .if !Len(esi)
void ArrayIndex(table(), Val(esi)) ; works with DWORD, QWORD and REAL8 arrays
.if dl
PrintLine esi, Str$(" is not a prime, sorry!!!! - the nearest prime is %i ", table(eax))
.else
PrintLine Str$("congrats, prime found at pos #%i !!", eax), Space$(32)
.endif
.Endw
EndOfCode
Tks, JJ :)
Found only a small issue. Whenever the searching number is bigger or equal to the last one on the table it should return the last one and not 2 before.
For example, i gave a try with only 10 numbers to search:
Table = 101, 103, 107, 109, 113, 127, 131, 137, 139, 149
(So, the Index/Pos = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Number is smaller or equal to the 1st one is ok :t Ex:
Number to Search = 100. Return nearest number is 101. (So, index = 0) OK !! :t
Number to Search = 101. Return nearest number is 101. (So, index = 0) OK !! :t
Numbers in between are Ok :t
Number to Search = 104. Return nearest number is 103. (So, index = 1) OK !! :t
Number is equal,is ok only when it is not the last one. Ex:
Number to Search = 103. Return index = 1 OK !! :t
Number to Search = 139. Return index = 8 OK !! :t
But....
Number to Search = 149. Not found. Return index should be 9.
but...when Number is bigger or equal to the last, it is returning 2 positions backwards and not the last one
Number to Search = 149. Not finding the proper number. Is giving a message of nearest The correct should be 149. So, index (Pos from 0 to XX) = 9
Number to Search = 150. Return nearest number is 139. The correct should be 149. So, index (Pos from 0 to XX) = 9
Number to Search = 151. Return nearest number is 139. The correct should be 149 So, index = 9
Number to Search = 2751. Return nearest number is 139. The correct should be 149 So, index = 9
Btw. the same issue i described happens when the size of the table is odd. For example , table size = 11
Table = 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 177
(So, the Index/Pos = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Number to search = 149; Found at pos 8 (139) rather then 9
It cannot find the number and, this time (For odd sized table), is returning 3 positions backwards, rather then 2 when the same error happens for even sized table.
Thanks a lot, Guga. I'm working on it...
You´re welcome, JJ :t :t :t
Thank you for the effort. This function will be very helpful for the CieLCH functions i´m making. I´m still working on the pdf i told. I finished part of it, but still trying to find the limits of all those equations. For what i saw so far, those equations are utterly incorrect, since they allows the user to input any RGB value despite the fact that some of those combination simply don´t matches to the results of their own formulas. The major problem is find a way to make them work ok, without using incorrect RGB values whose combinations, simply were impossible on the CieLab/CieLCH color spaces. This is the main reason why the backwards convertion allows clipping and generate incorrect results.
For example, when the user inputs a RGB value originate form a HSL convertion it is not guaranteed that it will result the proper Lab or LCH values from the perceptual colorspaces, since the input can be a combination of colors that don´t actually "exists".
Update 8 February 2019 (http://masm32.com/board/index.php?topic=94.0):
- ArrayIndex(someArray(), findnumber) is now working properly
- three new macros Log2, LogE, Log10:
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals REAL10 ct, tmp10
Init
For_ ct=1.5 To 10.0 Step 0.5
Print Str$(" Log2(%2f)", ct), Str$("\t%Jf ", Log2(ct)v), Str$("\t%Jf ", LogE(ct)v), Str$("\t%Jf\n", Log10(ct)v)
Next
void Log10(123.4567890)
fadd FP4(3.0)
ExpXY(10.0, ST(0), tmp10) ; calculates 10^ST(0) and saves it to tmp10
Inkey Str$("The value of tmp10 is now %f", tmp10)
EndOfCode
Output:
Log2(1.5) 0.5849625007211561815 0.4054651081081643820 0.1760912590556812421
Log2(2.0) 1.000000000000000000 0.6931471805599453094 0.3010299956639811952
...
Log2(9.5) 3.247927513443585494 2.251291798606495151 0.9777236052888477664
Log2(10.0) 3.321928094887362348 2.302585092994045684 1.000000000000000000
The value of tmp10 is now 123456.8
Update 12 February 2019 fixes a minor glitch in the editor (http://masm32.com/board/index.php?topic=94.0). As a side effect, a request by HSE to set the foreground colour (http://masm32.com/board/index.php?topic=5314.msg78962#msg78962) has been answered: YES it works now.
The snippets collection (\Masm32\MasmBasic\Res\MbSnippets.asc) has one problem with the ArraySet examples:
Dim MyNum(5) As DWORD ; create an array with 6 elements (0 .. 5)
ArraySet MyNum() = 11, 22, 33, 44, 55, 66 ; assign values
This syntax is obsolete and crashes, unfortunately. The proper way to handle this is like this:
ArraySet MyNum() As DWORD = 11, 22, 33, 44, 55, 66 ; create an array and assign values
xor ecx, ecx
.Repeat
mov MyNum(ecx), Rand(12345)
PrintLine Str$(ecx), Tb$, Str$(MyNum(ecx))
inc ecx
.Until ecx>=MyNum(?)
First, a DWORD array gets created, and 6 values are being assigned.
The loop replaces these values with random ones (range 0... 12344) and prints them.
Note a tricky little detail: .Until ecx>=MyNum(?) exits the loop when the current number of elements is reached. Take the = away, and you'll get an endless loop because when assigning a value to the last element+1, the array gets automatically expanded. This is not a bug, it's a feature of dynamic arrays.
Update 2 April '19 (http://masm32.com/board/index.php?topic=94.0) adds a bunch of improvements under the hood, check this Gui programming post (http://masm32.com/board/index.php?topic=7722.msg85206#msg85206) for an example. Inter alia, the new CanvasZoom macro allows to "zoom" a control:
GuiControl MyList, "listbox", x800, w200 ; put the box at x=80% width, full height
GuiControl MyImg, "canvas", w800, h500 ; images have width 80%, height 50%
GuiControl MyMap, "canvas", y500, h500, w800 ; same but at y=50% of height
...
Event Key
Switch_ VKey ; press M or I to zoom a canvas control (press twice to toggle)
Case_ VK_I: CanvasZoom MyImg, MyList ; zoom the image, hide the listbox
Case_ VK_M: CanvasZoom MyMap, MyList ; zoom the map, hide the listbox
Endsw_
Attached an image viewer; extract the exe to a folder that contains images (jpg, png, animated gif), then run the exe.
MasmBasic was updated (http://masm32.com/board/index.php?topic=94.0), version 8 May features some improvements under the hood, inter alia building a library has become a lot faster because it will no longer do a full rebuild (unless you use Shift F6).
As a side effect, RichMasm now supports the conversion of a library folder into a single source (the MasmBasic library is indeed one fat 2.2 MB file containing 33 modules). To test this feature, extract the attached files to a folder of your choice, then either drag a folder over the exe, or open a DOS prompt and type e.g. BuildTheLibSource.exe \Masm32\m32lib
Soon after, RichMasm will show you more or less this:
include TestFile.asm
OxPT_LibName \fullpath\MyLib
OPT_DelTmp 0
OPT_DelObj 0
OPT_Tgt rml ; RichMasmLibrary
OPT_Linker link ; polink does not recognise certain options
OPT_Arg1 "Hello coder, how are you?" ; for testing
LibMod AA: a2dw
; #########################################################################
; --------------------------------------
; This procedure was written by Iczelion
; --------------------------------------
.386
.model flat, stdcall ; 32 bit memory model
... etc ...
Hit F6 and watch the library being built. By default, it will be named BuildLib.lib - move it wherever you need it, the little TestFile.asm includes it "as is", i.e. as BuildLib.lib
What is the advantage of one big source file, instead of 237 tiny modules? It surely is a matter of taste, but, for example, you can search the source for mov e*, 0 to do a bit of maintenance (Intel says xor reg32, reg32 is the right thing to do). Plus comfortable navigation, highlighting of critical parts, etc - it's not meant for bare metal purists :P
splitting / combine source is a good idea.
easy too see what parts are changes, time stamp.
a common keyword for it might be usable ?
Find in files helps finding things, but often too many files to open in an editor.
MasmBasic.lib:
almost 250 symbols in 33 modules, still some work to do ?
PS: ml and pocc have a same problem, no COMDAT support :(
Quote from: TimoVJL on May 09, 2019, 12:35:23 AM
splitting / combine source is a good idea.
easy too see what parts are changes, time stamp.
I use a checksum for the part between
LibMods. When working inside the source, RichMasm remembers the last 8 edit positions (and saves them with the file!). By pressing Alt Left / Alt Right, you can jump between them. Hitting Alt Right several times brings you always back to the last edit. Thus, even if you stopped working on a source months ago, the editor will remember what you were last working on. Extremely handy in my experience. I hate editors that open a file, and you always stare at the top of the file.
QuoteMasmBasic.lib:
almost 250 symbols in 33 modules, still some work to do ?
Not all modules can be neatly separated, unfortunately. This is mainly because of the fast circular buffer and the array engines; many modules use them.
Hi jj,
How can i get the returned value of Split$ (number of found substrings)?
MOV EBX,Split$("Masm32 is great", " ", My$())-1 ;Does not work
Let EBX = Split$("Masm32 is great", " ", My$())-1 ;Does not work
Hi,
The example in the manual has a FOR counter:
For_ ct=0 To Split$("Masm32 is great", " ", My$())-1
PrintLine "[", My$(ct), "]"
Next
Since Split$() (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1320) returns the number of strings in eax, you could write this also as
void Split$("Masm32 is great", " ", My$())
For_ ct=0 To eax-1
PrintLine "[", My$(ct), "]"
Next
The example returns 3 strings, so this is for x=0 ... 3-1, given that arrays are zero-based. The problem in your example is the -1. You are writing MOV EBX, eax-1, and indeed, that does not work. Take away the -1, and all is fine.
Re your second example: Let (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1132) is for strings only.
Thanks for the feedback - I will modify the manual to make that point clearer :Thmbsup:
Thank you, that works now compiled without error.
I have one more question
Is it possible to get the Array size?
Dim MyBuffer(10) As BYTE
How can i get the size of this buffer?
I have looked the manual and couldn't find what i am looking for.
If you mean the number of elements: mov ecx, somearray(?)
Thanks. It works perfect. Very useful library :D
Thanks. Note that you can, but you don't have to, specify the array size. This is legal code:
xor ecx, ecx
Dim MyBuffer() As BYTE ; no size!
.Repeat
mov MyBuffer(ecx), cl
inc ecx
.Until ecx>100
Inkey "hit any key"
Arrays are dynamic, they auto-expand when the index (ecx in this case) hits the allocated number. You can't do a mov MyBuffer(1000), 123 though - the loop must increment the counter from the bottom.
Update 4 August 2019 (download (http://masm32.com/board/index.php?topic=94.0)):
- added a warning to RichMasm for a hilarious MASM bug where a constant passed as e.g. SS_LEFT or WS_BORDER was not recognised as a constant by ML.exe:
DlgControl dcStatic, "some text", SS_LEFT or WS_BORDER, 1, -7, 60.0
RichMasm will now add a "(1): Brackets around paras?" at the end of the output window. This may seem ridiculous but understanding the non-logic and misleading error messages of ML took me several hours, so I decided to warn myself next time.
- new macro ArrayFind(strings$(), "match", [mode], [startindex]):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Recall "\Masm32\include\Windows.inc", L$()
Print Str$("%i lines found in Windows.inc\n", eax)
.if ArrayFind(L$(), "Hutch")
PrintLine Trim$(L$(eax)) ; Original file 1998 hutch
.endif
xor ecx, ecx
.While 1
.Break .if ArrayFind(L$(), "MACRO", 1, ecx)<0 ; mode 1: case insensitive; see Instr_(...) (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153)
xchg eax, ecx
PrintLine Str$("line %i\t", ecx), L$(ecx)
inc ecx
.Endw
MsgBox 0, "ok?", "Hi", MB_OK
EndOfCode
Project attached.
We know the trolling pleasure you have in ranting Microsoft (and not only Microsoft). :badgrin:
However, the MASM BASIC macro (DlgControl MACRO ctrlType, szText, dstyle, etc) you provided as an example is buggy.
Look here:
if (dstyle and SS_ICON) eq SS_ICON
It is completely different to pass SS_LEFT or WS_BORDER and to pass (SS_LEFT or WS_BORDER). Macros are not functions, just in case you don't know.
BTW, I am not studying MASM BASIC at this time, I was looking at the latest posts and noticed this perl. :skrewy:
Yeah, completely different:
include \masm32\include\masm32rt.inc ; plain Masm32, no MasmBasic required
rant MACRO par1, par2, par3
Local tmp$
tmp$ CATSTR <Paras passed: p1=>, <par1>, <, p2=>, <par2>, <, p3=>, <par3>
% echo tmp$
print "Test "
print hex$(par1), 9
print hex$(par2), 9
print hex$(par3), 9
if (par2 and WS_BORDER) eq WS_BORDER
print "WS_BORDER passed "
endif
print chr$(13, 10)
ENDM
.code
start:
rant 1, SS_LEFT, 3
rant 2, WS_BORDER, 3
rant 3, SS_LEFT or WS_BORDER, 3
rant 4, WS_BORDER or SS_LEFT, 3
rant 5, (SS_LEFT or WS_BORDER), 3
rant 6, (WS_BORDER or SS_LEFT), 3
inkey
exit
end start
And you shouldn't feel ashamed for studying MasmBasic macros. There is a lot to learn for you :cool:
deleted
Quote from: nidud on August 05, 2019, 07:18:08 AM
if ((dstyle) and SS_ICON) eq SS_ICON
Thanks, Nidud, I see. Irrelevant for this specific macro (it works indeed), but there may be cases where it matters. Here is one, building on the previously posted example:
include \masm32\include\masm32rt.inc
rant MACRO par1, par2, par3
Local tmp$
tmp$ CATSTR <Paras passed: p1=>, <par1>, <, p2=>, <par2>, <, p3=>, <par3>
% echo tmp$
print "Test "
print hex$(par1), 9
print hex$(par2), 9
print hex$(par3), 9
if ((par2) and WS_BORDER) eq WS_BORDER ; Nidud's solution: (SS_RIGHT or WS_BORDER) and WS_BORDER
print "WS_BORDER passed "
endif
if (par2 and WS_BORDER) eq WS_BORDER ; fails: SS_RIGHT or WS_BORDER and WS_BORDER
print " +"
endif
print chr$(13, 10)
ENDM
.code
start:
rant 1, SS_RIGHT, 3
rant 2, WS_BORDER, 3
rant 3, SS_RIGHT or WS_BORDER, 3
rant 4, WS_BORDER or SS_RIGHT, 3
rant 5, (SS_RIGHT or WS_BORDER), 3
rant 6, (WS_BORDER or SS_RIGHT), 3
inkey
exit
end start
Test 3 fails:
Test 00000001 00000002 00000003
Test 00000002 00800000 00000003 WS_BORDER passed +
Test 00000003 00800002 00000003 WS_BORDER passed
Test 00000004 00800002 00000003 WS_BORDER passed +
Test 00000005 00800002 00000003 WS_BORDER passed +
Test 00000006 00800002 00000003 WS_BORDER passed +
This is code from an old plugin posted here two years ago (http://masm32.com/board/index.php?topic=5314.msg63462#msg63462):
DlgControl dcEdit, wRec$(ini$(4)), WS_BORDER, 89.0, -6, 11.0, , ID_MODE2 ; x, y only, the macro will assign width, height and ID; OPT_Assembler mlv615
if 0
DlgControl dcStatic, "Files containing both strings:", SS_LEFT or WS_BORDER, 1, -7, 60.0 ; THIS ONE CHOKES
DlgControl dcStatic, "maxMB=", SS_LEFT, 73.0%, -7, 31%
elseif 0
DlgControl dcStatic, "Files containing both strings:", (SS_LEFT or WS_BORDER), 1, -7, 60.0 ; this one is OK - Nidud's trick with the brackets works!!
DlgControl dcStatic, "maxMB=", SS_LEFT, 73.0%, -7, 31%
else
DlgControl dcStatic, "Files containing both strings:", SS_LEFT or WS_BORDER, 1, -7, 60.0 ; guess what?
DlgControl dcStatic, "maxMB=", SS_LEFT, 73.0%, -7, 31% ; this one is also OK!!
endif
The interesting part is that, under the hood, Nidud's suggestion has been implemented:
if ((dstyle) and SS_ICON) eq SS_ICON
and ch, 10111111b ; clear bit 14
endif
So it should not matter whether we use (SS_LEFT or WS_BORDER) or SS_LEFT or WS_BORDER
But it does, as case 2 shows! Now the hilarious part is that it works in case 3.
Needless to say that UAsm and AsmC have no problem at all - this is a MASM only bug! Project attached.
Table 1.3 Operator Precedence
Precedence Operators
1 ( ), [ ]
2 LENGTH , SIZE , WIDTH , MASK, LENGTHOF, SIZEOF
3 . (structure-field-name operator)
4 : (segment-override operator), PTR
5 LROFFSET , OFFSET , SEG , THIS , TYPE
6 HIGH , HIGHWORD , LOW , LOWWORD
7 + ,– (unary)
8 *, /, MOD , SHL , SHR
9 +, – (binary)
10 EQ , NE , LT , LE , GT , GE
11 NOT
12 AND
13 OR , XOR
14 OPATTR , SHORT , .TYPE
Thanks, Sinsi - this is already fixed with Nidud's suggestion to use brackets: if ((dstyle) and SS_ICON) eq SS_ICON
To my big surprise, I discovered that, after applying that fix, the line that choked was no longer the SS_LEFT or WS_BORDER line but rather the line that followed - see snippet above. After some trial and error, I discovered that cases 1 and 3, although almost identical, act differently:
case 1: DlgControl dcStatic, "maxMB=", SS_LEFT, 73.0%, -7, 31%
case 3: DlgControl dcStatic, "maxMB=", SS_LEFT, 73.0%, -7, 31% ; this one is also OK!!
The first one chokes, the second one is OK. And of course, both are OK for UAsm and AsmC.
8.14.5 Macro Parameter Expansion and Macro OperatorsQuoteOne possible solution, that works well for macros like the above, is to put parentheses
around macro parameters that occur within expressions inside the macro.
http://www.phatcode.net/res/223/files/html/Chapter_8/CH08-7.html
EDIT: to avoid further misunderstanding, only documentation for that ?
QuoteThe problem above occurs because MASM simply replaces a formal parameter by the actual parameter's text, not the actual parameter's value. This pass by name parameter passing mechanism should be familiar to long-time C and C++ programmers who use the #define statement. If you think that macro (pass by name) parameters work just like Pascal and C's pass by value parameters, you are setting yourself up for eventual disaster.
One possible solution, that works well for macros like the above, is to put parentheses around macro parameters that occur within expressions inside the macro. Consider the following code:
Yes, Timo, but it's not relevant here. Or, rather: it does work if you put parentheses around (x or z) but if you don't put these parentheses, all paras are passed correctly to this macro but the macro in the next line chokes.
And to make things perfect, you can make it assemble if ... tara! ... you add a comment to the next line:
case 1: DlgControl dcStatic, "maxMB=", SS_LEFT, 73.0%, -7, 31%
case 3: DlgControl dcStatic, "maxMB=", SS_LEFT, 73.0%, -7, 31% ; this comment makes the line assemble!!
If there is no comment, you get error A2026: constant expected - and that is complete BS. It's a MASM bug, that's all. Of the same kind as the inability to deal with the "#" character if it's not at a certain position inside the include file. I can't find the reference right now, but that was another ML bug that drove me crazy. My suspicion is that during macro processing, some buffers don't get delimited properly, but that is impossible to chase.
MASM has some serious problems, and I would ditch it completely in favour of UAsm or AsmC if there wasn't a bit of nostalgia around to stick with the original M$ product.
Timo,
I use all these macros on a daily basis, they work just fine. The problem is really some kind of buffer overflow in MASM that makes it choke with the % and # characters. I opened a separate MASM bug post with the complete example. (http://masm32.com/board/index.php?topic=8022.0)
The new MasmBasic version (http://masm32.com/board/index.php?topic=94.0) has fixes for the brackets bug, allows using e.g. 12.3% in the first DlgControl (that was the DlgDefY issue), and adds a specific warning to the output window if RichMasm sees "error A2026:constant expected".
Thanks a lot, Timo, Nidud and Sinsi, for your help.
MasmBasic version 26 October 2019 is online. (http://masm32.com/board/index.php?topic=94.0)
Changes:
- the RichMasm editor lists now macros and procs correctly, as in the image below
- \Masm32\MasmBasic\MbGuide.rtf got a Table of Contents
- For_ ... Next (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1185) with floats follows a different logic now:
* previously, the step was added to the float counter (fct in the example below). For small steps and REAL4 counters, significant deviations could accumulate
* the new version calculates fct as endvalue - step*(total - current iterations), which is much more exact.
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals fct:REAL4
Init
For_ fct=1.5 To 2.0 Step 0.01 ; counter is a float, and therefore needs to be
Print Str$("%Jf\n", fct) ; previously defined in .data? or with SetGlobals
Next
Inkey "ok?"
EndOfCode
Version 7 December 2019 is online (http://masm32.com/board/index.php?topic=94.0). Minor improvements, e.g. it's now possible to add a legend to an ArrayPlot (project attached):
(http://www.jj2007.eu/pics/LifeExpScreenshot.jpg)
The code required to add the legend:
ArrayPlot RgbCol(192, 255, 255) ; init & set background
If_ useLegend Then Legend ld$(), mr, hLegendFont ; corners: ul, ur, ll, lr, mr
...
ArrayPlot exit, 0005000032#T title$, fcol Black ; finish with a title, xxxxyyyyfsize
ld$() can be any Utf8 string array; mr indicates the position middle/right
To build the project,
- install the latest MasmBasic version (http://masm32.com/board/index.php?topic=94.0)
- extract the archive below to a folder on your Masm32 drive
- open LifeExpOECD.asc in RichMasm (\Masm32\MasmBasic\RichMasm.exe)
- hit F6
Hi jj2007,
just downloaded your MasmBasic - interesting! I think there will be questions ...
JK
Go ahead :biggrin:
The idea is very cool, the implementation (RichMasm) is ... not easy to get used to. I would like to discuss a few things (MasmBasic and FreeBASIC related) in private - would you please drop me a mail at "jklwn44 at mail dot de".
Email sent, although I prefer discussing here in this thread, or, if necessary, via PMs.
Re RichMasm, there are some posts here (http://masm32.com/board/index.php?topic=5314.0). I know it looks different, but I couldn't do any serious work with one of the standard editors. For example, the RichMasm source has currently 21,000 lines, try working with such a source without the listbox, the bookmarks and the history (Alt cursor left/right) :cool:
Note you can build FreeBasic sources with RichMasm, but a little add-on is needed. Let me know if you want to test it.
My biggest nuisance with RichMasm is that the MRU is limited to 25 files. The library itself is easy to handle, just one big file with 30 or so modules, but I have over 5,000 sources hanging around, and I am always playing with a dozen new ideas.
Update 22 Feb 2020: (http://masm32.com/board/index.php?topic=94.0)
- minor improvements of the RichMasm editor
- changes to the deb macro (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019):
- displaying a string by address is now possible via e.g. deb 4, "test", $addr MyAnsi$, $$addr MyWide$
- the handling of strings in structures was improved
- debugging the FPU was improved - now the state of the registers is displayed:
include \masm32\MasmBasic\MasmBasic.inc
Init
FpuFill ; fill FPU with 1001.0 ... 1008.0
ffree st(7) ; create some problems
fldz
fldpi
ffree st(5)
ffree st(7)
fldl2e
deb 4, "FPU filled, NaN in ST1, zero in ST2, ST6 empty", ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7)
fstp st
ffree st(7)
ffree st(6)
ffree st(5)
ffree st(4)
ffree st(3)
deb 1, "As previous, one fstp st plus 5*ffree", ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7)
EndOfCode
You may wonder why there are five ffree instructions: it is a special service for the Windows 10 users (http://masm32.com/board/index.php?topic=8363.msg91594#msg91594) :bgrin:
Console output (deb 1 produces a MsgBox):
FPU filled, NaN in ST1, zero in ST2, ST6 empty
ST(0) 1.442695040888963407
ST(1) - NaN -
ST(2) zero
ST(3) 1001.000000000000000
ST(4) 1002.000000000000000
ST(5) 1003.000000000000000
ST(6) empty 1004.000000000
ST(7) 1005.000000000000000
- various trigonometric functions added (source attached):
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals fct:REAL8
Init
Cls
Print cfm$("degrees\tSinus\tCosinus\t Tangens Cotangens")
For_ fct=0.1 To 360.0 Step 15.0
Print Str$("\n%__i", fct), Str$("\t%3f", Sinus(fct)v), Str$("\t%3f", Cosinus(fct)v), Str$("\t %3f", Tangens(fct)v)
Print At(37) Str$("%3f", Cotangens(fct)v)
Next
Print
Print Str$("\nrTangens(PI/3)=30° \t%3f", rTangens(0.5236)v)
Print Str$("\nrCotangens(PI/6)=15° \t%3f", rCotangens(0.2618)v)
Print Str$("\nArctangens(0.268) \t%3f", Arctangens(0.268)v)
Print Str$("\nArctangens(0.577) \t%3f", Arctangens(0.577)v)
Print Str$("\nArctangens(1) \t%3f", Arctangens(1)v)
Print Str$("\nArctangens(1.732) \t%3f", Arctangens(1.732)v)
Print Str$("\nArctangens(60/30) \t%3f", Arctangens(60, 30)v) ; ideally opposite/adjacent sides of a rectangular triangle
Print Str$("\nArctangens(4/3) \t%3f", Arctangens(4, 3)v) ; Pythagoras: 25=16+9
EndOfCode
Output:
degrees Sinus Cosinus Tangens Cotangens
0 0.00175 1.000 0.00175 573.
15 0.259 0.966 0.268 3.73
30 0.500 0.866 0.577 1.73
45 0.707 0.707 1.00 1.00
60 0.866 0.500 1.73 0.577
75 0.966 0.259 3.73 0.268
90 1.00 0.0 -3.69e+19 -2.71e-20
105 0.966 -0.259 -3.73 -0.268
120 0.866 -0.500 -1.73 -0.577
135 0.707 -0.707 -1.000 -1.00
150 0.500 -0.866 -0.577 -1.73
165 0.259 -0.966 -0.268 -3.73
180 0.0 -1.00 5.42e-20 1.84e+19
195 -0.259 -0.966 0.268 3.73
210 -0.500 -0.866 0.577 1.73
225 -0.707 -0.707 1.00 1.00
240 -0.866 -0.500 1.73 0.577
255 -0.966 -0.259 3.73 0.268
270 -1.00 0.0 -5.27e+18 -1.90e-19
285 -0.966 0.259 -3.73 -0.268
300 -0.866 0.500 -1.73 -0.577
315 -0.707 0.707 -1.00 -1.000
330 -0.500 0.866 -0.577 -1.73
345 -0.259 0.966 -0.268 -3.73
360 0.0 1.00 1.08e-19 9.22e+18
rTangens(PI/3)=30° 0.577
rCotangens(PI/6)=15° 3.73
Arctangens(0.268) 15.0
Arctangens(0.577) 30.0
Arctangens(1) 45.0
Arctangens(1.732) 60.0
Arctangens(60/30) 63.4
Arctangens(4/3) 53.1
MasmBasic of 2 May 2020 (http://masm32.com/board/index.php?topic=94.0) features the Say macro (source included). Simple example:
include \masm32\MasmBasic\MasmBasic.inc
Init
Say "Hello World"
EndOfCode
Attached is a project (tested with Win10, Win7 and WinXP) that might amuse Hutch - here is the complete source, it's a fascinating lecture :bgrin:
include \masm32\MasmBasic\MasmBasic.inc
Init
Say wRec$(NoTag$(FileRead$("http://masm32.com/why.htm")))
EndOfCode
Using Say from a GUI application is also quite easy:
- in RichMasm's File menu, click "New Masm source" to open the greenish window with the templates
- pick "controls" (the third item in the list with white background)
- hit F6 to test it, then check the syntax in the source.
Excerpt from \Masm32\MasmBasic\MbGuide.rtf:
Sound
Sound "880:200" ; plays frequency 880Hz for 200 ms; allowed separators are space, tab, / and :
Sound "880/200/150" ; plays frequency 880Hz for 200 ms, followed by 150 ms of silence
Sound 111 ; plays a wav resource with ID 111 (in rc file: 111 WAVE "hello.wav")
Sound "hello.wav" ; plays a file directly (wav only)
Sound "hello.mp3" ; plays a file in its associated player
Sound "大桥在混乱的水.mp3" ; Unicode names are allowed
Sound wCL$() ; even if passed via the commandline
Rem - The simple "frequency:duration" syntax works on Windows 7 and higher but not on Windows Vista;
a minimum duration of about 90...100 ms is required
- PlaySound/Beep/ShellExecute results can be checked with Err$()
Say
include \masm32\MasmBasic\MasmBasic.inc
Init ; select Init and hit F6
Say "Hello World"
Say "Low and slow", SetVolume(50), SetRate(-7) ; you can use some methods of the ISpVoice interface
; Say wWin$(hEdit) ; any Unicode string is ok
; Say FileRead$("TTS_Unicode.txt")
; Say wRec$(FileRead$("TTS_Ansi.txt")) ; conversion necessary
EndOfCode
Rem uses ISpVoice
P.S.: Does anybody know how to use SpCreateBestObject (https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms717500(v=vs.85))? In theory, SetVoice(...) should work with the Say macro, but I can find only one female voice under Win7 and Win10.
Speaking of source code, literally. :cool:
Exactly :tongue:
Here is another one for you: it reads the Say macro source for you :bgrin:
include \masm32\MasmBasic\MasmBasic.inc
Init
Say wRec$(Extract$(FileRead$("\masm32\MasmBasic\MasmBasic.inc"), "Say MACRO", "ENDM", xsIncL or xsIncR, 99))
EndOfCode
Obviously, you need the last MB installation (http://masm32.com/board/index.php?topic=94.0) to extract the macro from the inc file, otherwise Extract$(..) (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1156) will only return a question mark.
Another variant, reading a very old short source:
include \masm32\MasmBasic\MasmBasic.inc
Init
Recall "\Masm32\examples\Tut17\2\USEDLL.ASM", L$()
For_ each ecx in L$()
PrintLine ecx
Say wRec$(ecx), SetRate(5)
Next
EndOfCode
Couldn't read MasmBasic.inc ( I haven't installed MasmBasic )
I had a plan ( never came so far to try it ) to write something with SAPI to copy speech to memory as a wav file.
I'm not sure anymore, think it should be possible with SAPI...
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms719484(v%3Dvs.85)
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms722562(v%3Dvs.85)
https://stackoverflow.com/questions/20498004/how-to-save-sapi-text-to-speech-to-an-audio-file-in-vbscript
Quote from: TimoVJL on May 03, 2020, 05:24:05 PM
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms719484(v%3Dvs.85)
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms722562(v%3Dvs.85)
https://stackoverflow.com/questions/20498004/how-to-save-sapi-text-to-speech-to-an-audio-file-in-vbscript
Thanks! :thumbsup:
Quote from: jj2007 on May 02, 2020, 09:29:58 PMObviously, you need the last MB installation (http://masm32.com/board/index.php?topic=94.0) to extract the macro from the inc file, otherwise Extract$(..) (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1156) will only return a question mark.
Quote from: Siekmanski on May 02, 2020, 11:01:00 PM
Couldn't read MasmBasic.inc ( I haven't installed MasmBasic )
No problem, Marinus - you just wanted to demonstrate that you would never, ever install MasmBasic. That's fine for me :tongue:
Has anybody at least tried to use SpCreateBestObject?
:tongue:
What SAPI 5 version do you have?
I have 5.1.
I could find SpCreateBestObject in the Help file but not in the includes. ( could be I'm missing some files )
Is it a helper function from a lib?
I can't remember if there was also a lib included in the SAPI5.1 SDK.
Why not enumerate all the voices yourself and pick the one you want to use, or is there more to the SpCreateBestObject?
I have 5.3, which should have it: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms717500(v%3Dvs.85)
invoke LoadLibrary, Chr$("C:\Windows\System32\Speech\Common\sapi.dll")
fdeb 4, "LL", eax
.if eax
push eax
invoke GetProcAddress, eax, Chr$("SpCreateBestObject")
fdeb 4, "GPA", eax
call FreeLibrary
Inkey
Exit
.endif
NOT FOUND.
Just had a look in the Windows v7.1 SDK,
There I found the sapi.lib and the sapi51 and sapi53 includes, no SpCreateBestObject ( also not in the sapi.lib ) :sad:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\sphelper.h
template<class T>
HRESULT SpCreateBestObject(
const WCHAR * pszCategoryId,
const WCHAR * pszReqAttribs,
const WCHAR * pszOptAttribs,
T ** ppObject,
IUnknown * pUnkOuter = NULL,
DWORD dwClsCtxt = CLSCTX_ALL)
{
HRESULT hr;
Looks like a function.
Do you have the Sapi5.3 SDK installed? Maybe there is a lib....
I have over 3GB of Visual Studio 14.0 hanging around in C:\Program Files (x86)\Microsoft Visual Studio 14.0 - no SpHelper found in 7789 folders, but 224 lib files. None of them has SpCreate*
I wonder if it's Windows CE only: https://docs.microsoft.com/en-us/previous-versions/ms937518(v%3Dmsdn.10)
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms717321(v%3Dvs.85)
QuoteMicrosoft Speech API 5.3
Helper Functions
Helper functions are available as a convenience to programming. Since many of the procedures use the same few methods or calls in the same sequence each time, these functions are available to consolidate those standard sequences. In all cases, the functions represent nothing more than the individual steps combined into one call; no additional features have been added or removed. Programmers are free to either use these functions or include the original lines of code. The function name attempts to clearly identify the purpose of the function itself.
The following helper functions are used with SAPI 5.
Token Helpers
SpCreateBestObject
SpCreateDefaultObjectFromCategoryId
SpCreateNewToken (by category ID)
SpCreateNewToken (by token ID)
SpCreateNewTokenEx (by category ID)
SpCreateNewTokenEx (by token ID)
SpCreateObjectFromSubToken
SpCreateObjectFromToken
SpCreateObjectFromTokenId
SpCreatePhoneConverter
SpEnumTokens
SpFindBestToken
SpGetCategoryFromId
SpGetDefaultTokenFromCategoryId
SpGetDefaultTokenIdFromCategoryId
SpGetDescription
SpGetSubTokenFromToken
SpGetTokenFromId
SpGetUserDefaultUILanguage
SpSetCommonTokenData
SpSetDefaultTokenForCategoryId
SpSetDefaultTokenIdForCategoryId
SpSetDescription
I have searched on my computer, found nothing.
Maybe you have succes with: IID_ISpObjectTokenCategory EnumTokens ?
Not yet. I guess it's useless anyways because I have only one voice installed. Extra voices cost real money.
There is a demo here (https://www.cereproc.com/en/node/645). Try with the text below - amazing!
There are many reasons why experienced programmers choose to write assembler code, performance issues where speed matters, the architectural freedom to lay out code in any way you like, the capacity to do things that cannot be done in many compilers but the main reason is simply because you can. Many conjure up the image of cobbling together a few DOS interrupts in unintelligible notation to prop up the shortcomings of compilers yet a modern assembler like MASM has the range of a high level language and can be written that way for high level code while retaining all of its power at the lowest level.
With the introduction of the 32 bit Windows API functions, MASM had access at the same functions that compilers had from the operating system but without the clutter and assumption of many of the compilers available. When you write Windows API code in MASM you get perfectly clear minimal precision code that leverages the full power of the Windows operating system and you get it at the code size you write, not with a pile of unwanted extras dumped into your executable by a compiler.
MASM has never been for the faint of heart, it is an uncompromised tool that has never been softened into a user friendly toy and it required the development of expertise to use correctly but for the programmer who already has experience in low level C and similar code, MASM offers power and flexibility that the best of compilers cannot deliver and contrary to popular opinion it can be developed and written at about the same development time as C code.
I heard the text from your example. :cool:
Copied it in the link you posted, there are some High Quality ones.
I have 2 amazingly High Quality SAPI5 Dutch female voices. (paid 200 euros for the 2 voices, today you can get 1 for 40 euros. )
Unfortunately they will only install on Windows 32bit. :sad:
I have downloaded the SDK from http://download.microsoft.com/download/B/4/3/B4314928-7B71-4336-9DE7-6FA4CF00B7B3/SpeechSDK51.exe
Mary & Mike don't work, and "Sample TTS voice" works but says most of the time "bla" (really :tongue:)
:biggrin:
https://harposoftware.com/en/search?controller=search&orderby=position&orderway=desc&search_query=italian&submit_search=
A test program for SAPI 5.x
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <sapi.h>
#pragma comment(lib, "ole32.lib")
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
ISpVoice * pVoice = NULL;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(&CLSID_SpVoice, NULL, CLSCTX_ALL, &IID_ISpVoice, (void **)&pVoice);
if (SUCCEEDED(hr))
{
hr = pVoice->lpVtbl->Speak(pVoice, L"<voice optional='Gender=Male;'>Hello world", 0, NULL);
//hr = pVoice->lpVtbl->Speak(pVoice, L"<voice required='Gender = Male;'>Hello world", 0, NULL);
//if (hr) hr = pVoice->lpVtbl->Speak(pVoice, L"<voice required='Gender = Female;'>Hello world", 0, NULL);
pVoice->lpVtbl->Release(pVoice);
pVoice = NULL;
}
CoUninitialize();
return 0;
}
Very interesting, Timo - I didn't know that you can specify options with XML tags:
hr = pVoice->lpVtbl->Speak(pVoice, L"<voice optional='Gender=Male;'>Hello world, I am a man", 0, NULL);
if (1)
hr = pVoice->lpVtbl->Speak(pVoice, L"<voice required='Gender=Female;'>Hello world, I am a woman", 0, NULL);
With this modification, I hear both strings spoken by the same female voice when built as X64, but only "I am a woman" when built as x86 :sad:
With MasmBasic:
Say wChr$("<voice optional='Gender=lgbt;'>Good morning")
For Gender=, everything works fine except Gender=male, which is mute :rolleyes:
Update 28 July 2020 (http://masm32.com/board/index.php?topic=94.0) (in response to fast median thread (http://masm32.com/board/index.php?topic=8671.msg95039#msg95039) and timings (http://masm32.com/board/index.php?topic=8688.msg95011#msg95011))
include \masm32\MasmBasic\MasmBasic.inc
Init
Dim MyArray() As REAL4 ; can be DWORD, REAL4 or REAL8
For_ ecx=0 To 99
Rand(-888.8, 999.9, MyArray(ecx)) ; put random numbers into the array
Next
PrintLine Str$("The elements:\t%i", MyArray(?))
PrintLine Str$("The columns:\t%i", MyArray(?cols)) ; will return 0: this array is one-dimensional
PrintLine Str$("The minimum:\t%f", MyArray(?min)v) ; the functions marked with v return the
PrintLine Str$("The maximum:\t%9f", MyArray(?max)v) ; value in ST(0); the v tells Str$() to discard
PrintLine Str$("The median:\t%f", MyArray(?median)v) ; ST(0) with fstp st after printing
PrintLine Str$("The mean:\t%9f", MyArray(?mean)v) ; ?average does the same as ?mean
PrintLine Str$("The sum: \t%9f", MyArray(?sum)v) ; sum of all elements
EndOfCode
The elements: 100
The columns: 0
The minimum: -884.9537
The maximum: 994.308716
The median: -8.574001
The mean: 35.9553806
The sum: 3595.53806
Cool, all in one. :cool:
Great work, JJ
One question about the median function.
Here
fld st
faddp st(2), st
fsub arrInf.yMin ; make positive
fmul arrInf.yRange ; normalise 0...99999
; fadd FP4(0.45)
fistp arrInf.yIndex ; we need a
mov eax, arrInf.yIndex ; reg32
inc dword ptr [edi+4*eax] ; Populate the Median buffer with the values as index numbers and keep track for duplicates in one go
dec ecx
jns aiPop ; 0 is still ok
the size of the Table (MedBuffer) used in edi must be the double when we are dealing with negative values, right ?
I mean, say i have limits from -255 to 255, then the total size of the table should be (256*4*2) ?
Also, since it will be subtracting the negative values to set onto the proper address of the table, should it calculate the median and preserve the sign in case the resultant median is also negative ?
I previously normalized the inputed data to -1 to 1, so i divided each value with 255. On your version, at that routine, i made the following port:
; [Med_MinVal_Normalized: R$ -1.0] = < --- The minimum value as set in arrInf.yMin already normalized
Do
fld F$esi | fsub R$Med_MinVal_Normalized | fmul R$Float255 | fistp D@Index | mov eax D@Index ; Multiplied the input with 255 to it points to the proper address on the table.
inc D$edi+eax*4 ; Populate the Median buffer with the values as index numbers
add esi ebx ; and keep track for duplicates in one go. And skip positions if needed
Repeat_Until_Zero ecx
Is this correct ? Will it result a negative median (thus, preserving the sign) if the median is, in fact, negative ?
Hi Guga,
In the example above the range of values is determined by the Rand (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1030)(-888.8, 999.9, destination). The normalisation takes care of negative numbers. In fact, the median for this dataset is slightly negative.
The minimum: -884.9537
The maximum: 994.308716
The median: -8.574001
The mean: 35.9553806
Hi JJ, ok, but how the normalization works ? The math operation, i mean.
I saw it takes the subtraction of the Maxvalue to the MinValue, but it will divide by what ?
Fraction = (Max-Min)/ WhatData ?
What Data is suppose to be divided with ? If we have negative numbers, it means we have double the amount of values, right ? ex, if the limits to be settled are -255 to 255, it means we have, in fact a limit of 255*2 data to load. So, if our Minimum value found is, let´s say -200 and Max is 185, then to apply the normalization, is correct to do this ?
Fraction = (185-(-200))(2*255) = (185+200)/510 = 385/510 = 0.754901961
So, our Fraction (arrInf.yRange) would be 0.754901961, right ?
And to recover the proper median at the end of the function, we do this ?
New Value = ValueFound/Fraction - Minimum Value ? = ValueFound/0.75490191 - (-200) ?
Quote from: guga on July 30, 2020, 12:11:06 PM
Hi JJ, ok, but how the normalization works ? The math operation, i mean.
Search for arrInf.yRange - it should be self-explanatory :cool:
New version online (http://masm32.com/board/index.php?topic=94.0)
There are numerous little improvements under the hood. One new feature: RichMasm knows a new option called "Close" (see the Capitals of Europe thread (http://masm32.com/board/index.php?topic=8808.0) for an example).
OPT_Close Capitals of Europe ; close the window before building
When testing a Windows program, I often forget to close it before hitting F6 (the build all key). Inevitably, the linker chokes because the exe is still running. Now with OPT_Close <the window title> RichMasm sends a WM_CLOSE message to the running exe, and it closes (unless there are data to be saved, of course). Problem solved :tongue:
Another new feature: the canvas control (for plots, images and maps, see e.g. GuiImage (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1375)) has now a right-click context menu for saving its content to the clipboard or to a file. It can also be zoomed to fill the entire client area.
The one-line If_ accepts now also Exist(), FileOpen$() etc args:
include \masm32\MasmBasic\MasmBasic.inc
Init
If_ Exist("*.bmp") Then PrintLine "yeah, ", Exist$, " exists"
If_ not Exist("no.bmp") Then Print "Nope, it does not exist"
EndOfCode
Btw did you know the difference between these two?
a) ; int 3
b) int 3
With a), hitting F6 builds and launches the executable
With b), hitting F6 builds and launches \Masm32\OllyDbg\ollydbg.exe <executable path>
Greetings from a lazy programmer :tongue:
New version online (http://masm32.com/board/index.php?topic=94.0)
Here is an attempt to use an I/O library to communicate with ports, inspired by this FreeBasic thread (https://www.freebasic.net/forum/viewtopic.php?f=18&t=28863):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Cls
if 0
Dll "InpOut32" ; WikiDll (https://wikidll.com/other/inpout32-dll); first three functions
else
Dll "DlPortIO" ; Scientific Software Tools at WikiDll (https://wikidll.com/scientific-software-tools-inc/dlportio-dll) ; next four
endif
Declare void Out32, 2 ; ushort port, data
Declare void Inp32, 2 ; ushort port, data
Declare IsInpOutDriverOpen ; no args
Declare DlPortReadPortUshort, 1 ; ushort port
Declare DlPortReadPortUlong, 1 ; int port
Declare DlPortWritePortUshort, 2 ; int port, data
Declare DlPortWritePortUlong, 2 ; int port, data
PrintLine Str$("Out32: %i", Out32(?)) ; prints the address or zero if the function was not found
If_ IsInpOutDriverOpen(?) Then <Print Str$("driver open: %i\n", IsInpOutDriverOpen())> ; crashes
If_ Out32(?) Then <Out32(111h, 222h)> ; crashes
If_ DlPortReadPortUshort(?) Then <Print Str$("read port: %i\n", DlPortReadPortUshort(99))> ; error message
PrintLine "done"
EndOfCode
The DLLs are available at various places, see links above, but it is unclear how they actually work. Inp32 and Out32 are actually straightforward, under the hood you see in al, dx and out dx, al, but the rest is badly documented.
What's new in MasmBasic then?
- SomeFunction(?) checks if the function has been loaded - see IsInpOutDriverOpen(?) above
- in console mode, you get feedback on Declare (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1018):
not found (line 9): Out32
not found (line 10): Inp32
not found (line 11): IsInpOutDriverOpen
Unrelated: $Data (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1290) accepts now empty strings. This was inspired by Guga's Resource String Table (http://masm32.com/board/index.php?topic=8828.0) thread. If, for example, you copy \Masm32\include\masm32rt.inc into a source (to display the strings, whatever), there are some empty strings, and they used to choke with $Data. This little problem has been solved*)
In case you want a huge string table copied from a text file:
- File/New/Masm source: pick the Console example
- between the include line and Init, paste the lines from the text file
- select the whole block
- press Alt R
- insert $Data ]#[ into the replace edit control, hit Return and confirm
- insert these three lines under Init (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1009):
Read my$()
For_ ecx=0 To eax-1
PrintLine my$(ecx)
Next
*) at least for UAsm and AsmC - M$ MASM misbehaves on this one, and for ML there is no workaround other than deleting the offending empty line; otherwise, the whole MasmBasic library is fully compatible with ML versions 6.15 ... 14 or so, but attention, some recent ML versions have ugly bugs (http://masm32.com/board/index.php?topic=6447.0). I strongly recommend to use UAsm (http://www.terraspace.co.uk/uasm.html).
Version 12 October is online (http://masm32.com/board/index.php?topic=94.0)
- version 3 of Capitals of Europe (http://masm32.com/board/index.php?topic=8808.0) will build with the latest MasmBasic package (maps with flicker-free Unicode tooltips)
- new macro LineNumber(buffer, search$):
include \masm32\MasmBasic\MasmBasic.inc
Init
Print Str$("The string 'Duplicate' is in line %i of Windows.inc", LineNumber(FileRead$("\Masm32\include\Windows.inc"), "Duplicate")+1)
EndOfCode
Output:
The string 'Duplicate' is in line 26900 of Windows.inc
Optional 3rd argument: mode as for Instr_() (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153), i.e. 1=case-insensitive, 2=first char of match case-insensitive, 4=full word...
Optional 4th argument: line delimiter char, e.g. 13 (default is 10=linefeed)
LineNumber() is not particularly fast, but it returns the #lines of Duplicate in Windows.inc in under 3ms on my trusty old Core i5 - reading the file included :cool:
Update 16 October 2020 is online (http://masm32.com/board/index.php?topic=94.0) and features a new StringBuild macro (http://masm32.com/board/index.php?topic=8853.msg96604#msg96604):
StringBuild edi ; ---------- start building the string
For_ ecx=1 To 70000
Let edi=CrLf$+"string "+Str$("#%i", ecx)
Next
StringBuild ; ---------- stop string building
For a 1MB string, the speed gain compared to Let my$=my$+"xx" is roughly a factor 1,000 :cool:
With e.g. StringBuild some$, 2000000 the default 1MB allocation can be adjusted if needed. For usedeb=1 (default), overflow will trigger a MsgBox; this costs a few bytes more but has practically no influence on performance.
GuiParas equ "Plotting a linear regression", w600, h300, col Pink, icon Plot, b RgbCol(0, 0, 0)
include \masm32\MasmBasic\Res\MbGui.asm
ArrayRead x() As REAL8, 90 ; get x+y arrays
ArrayRead y() As REAL8, 91 ; from resources
Dim y2() As REAL8 ; this array will hold the regression line
GetLinReg x(), y() ; set the A and B coefficients
For_ ecx=0 To eax-1 ; #elements in eax
SetFloat <y2(ecx)>=LinRegY(x(ecx)) ; <destination> brackets needed here
Next
Event Paint
ArraySet MyRange() As REAL4=-0.5, 0.0, 3.2, 50.0
ArrayPlot MyRange(XY), setrange
ArrayPlot x():y(), RgbCol(255, 255, 255, 0), 5
ArrayPlot x():y2(), RgbCol(160, 255, 0, 0), lines=3
ArrayPlot exit, "Linear regression"
EndOfCode
Rsrc
90 RCDATA "RegressionX.dat"
91 RCDATA "RegressionY.dat"
Rsrc
Source, exe and data files attached - building requires MasmBasic version 25 October 2020 (http://masm32.com/board/index.php?topic=94.0)
Version 27.10.2020: (http://masm32.com/board/index.php?topic=94.0)
- bugfix: ArrayStripDuplicates could set a faulty last value
- new: ArrayMinMax myarray(), minVar, maxVar (i.e. you can now specify two destination variables)
- new: AddFloat, e.g. SetFloat myRealX=123.456, AddFloat myRealX=[any immediate number or numeric variable]
- ArraySet accepts now variables, e.g. ArraySet xyarray() As REAL4=maxDate, 0.0, minDate, ecx
Finally, RichMasm's layout improved slightly: the pinboard has moved to the upper right corner, as shown below (this is the proc called by GuiImage (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1375) - a bit over 350 lines).
(http://www.jj2007.eu/pics/ImgPaintP.png)
MasmBasic gives net error when downloading. can someone give me a valid linlk?
http://masm32.com/board/index.php?topic=94.0 doesn't work for you? I just tested it, everything works as it should...
I found lovely music that doesn't distract me from coding: The Russian Guitars 1800-1850 (https://www.youtube.com/watch?v=dTdPizz7Dic)
Nice track, like it.
jj,
The new update seems to give errors about unresolved externals. Why?
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _CreateFontIndirectA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetOpenFileNameA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetOpenFileNameW@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetSaveFileNameA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetSaveFileNameW@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _SHBrowseForFolderA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _SHGetPathFromIDListA@8 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _CoTaskMemFree@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAB.obj) : error LNK2019: unresolved external symbol _StdOut@4 referenced in function _TestRetVal@0
Also, how can i redim an array that has been allocated by Dim?
Example:
Dim My$(999) As DWORD
Dim My$(new:1234)
Errors
Error A2102: Symbol not defined : new
The documentation is so confusing.
Quote from: 2B||!2B on December 07, 2020, 05:45:16 PM
The new update seems to give errors about unresolved externals. Why?
I've just downloaded the installer, and used it on a "virgin" Masm32 installation. Everything works fine... did you modify any Masm32 files? Does it work now, if yes: what did you change? I am curious what could be the cause, as I cannot reproduce this problem.
QuoteAlso, how can i redim an array that has been allocated by Dim?
Example:
Dim My$(999) As DWORD
Dim My$(new:1234)
Errors
Error A2102: Symbol not defined : new
When you add
As DWORD, MasmBasic assumes you want a numeric array. I will add an error message to catch this :cool:
include \masm32\MasmBasic\MasmBasic.inc
Init
Dim MyDouble() As REAL8 ; a numeric array
Dim My$() ; a string array
For_ ecx=0 To 9
Let My$(ecx)=Str$("This is string #%i", ecx) ; assign strings
Next
For_ ecx=0 To 9
PrintLine "[", My$(ecx), "]" ; display them
Next
Dim My$(new:99)
Print Str$("The new array has %i elements\n", My$(?))
For_ ecx=0 To 9
PrintLine "[", My$(ecx), "]" ; empty strings
Next
EndOfCode
QuoteThe documentation is so confusing.
Sorry for that... I'm not very good at writing help files, I know. Just ask if you run into a problem.
Quote from: 2B||!2B on December 07, 2020, 05:45:16 PM
The new update seems to give errors about unresolved externals. Why?
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _CreateFontIndirectA@4 referenced in function _MbCloseN@0 ...
Does anybody else have such problems? I can't reproduce it here...
Today's update (http://masm32.com/board/index.php?topic=94.0) simplifies the re-dimensioning of string arrays:
include \masm32\MasmBasic\MasmBasic.inc ; download
Init
Dim My$() ; create a string array
For_ ecx=0 To 99
Let My$(ecx)=Str$("String #%i", ecx)
Next
Print Str$("This array has %i elements\n", My$(?))
Dim My$() ; re-dim it
For_ ecx=0 To 9
Let My$(ecx)=Str$("New string #%i", ecx)
Next
Inkey Str$("The new one has %i elements\n", My$(?))
EndOfCode
Output:
This array has 100 elements
The new one has 10 elements
Attached the demo, but with code for a two-dimensional string array
Hi JJ,
Sorry for the late reply. Yes, i modded some masm32 inc files to remove the duplicate of include of files.
I think that is the cause of this issue. But previous version(not sure which one i currently use as i have no idea how to get the version) is working.
Quote from: 2B||!2B on December 15, 2020, 03:45:43 PM
Hi JJ,
Sorry for the late reply. Yes, i modded some masm32 inc files to remove the duplicate of include of files.
I think that is the cause of this issue. But previous version(not sure which one i currently use as i have no idea how to get the version) is working.
That is generally not a good idea, as you are no longer compatible with anybody else in the forum. And to my knowledge, duplicates of include files were never an issue, neither for MasmBasic nor for plain Masm32 SDK code (it shows in the output window if there are any duplicates).
As to the version: all files have a date+time stamp.
Just installed SetUpMasmBasic18Feb2021
My computer has a 3200 x 1800 native display (15 inch) and because many applications require the High DPI resolution - I have to set Windows 10 scaling to 100% (default is 200%).
However, now all the text is "half height" (compared to a standard display)!
The usual windows [Ctrl] + does not work here to increase text size, and using [Windows Key] + is a "pain" to keep on doing. Because I have applications running in the background needing scaling 100, I do not constantly want to switch scaling 100 to 200 and vice versa.
Any way to increase text size for the IDE etc?
Quote from: Richard on March 27, 2021, 04:48:14 AMAny way to increase text size for the IDE etc?
Hi Richard,
Hold Control and move the mouse wheel forward. When you are ok with the font, press Alt Z.
Note this is not possible with the system font; if you encounter a template with that font, press Ctrl A to select everything, then go to the menu "Edit & Format" and select "Proportional". Let me know if it works, please :cool:
@jj2007
Thanks for [Ctrl] mouse wheel Tip - very helpful for me (eventually will try out template situation).
Now as long as I remember to use [Ctrl] mouse wheel I should be OK (in general)
Problems I have are that
the top row menu options File Edit&Format etc is not permanently visible (sometimes the case)
once I have opened an .asc file (etc) (yellow background) - I cannot seem to be able to get back to the "opening screen" (green background) UNLESS I just reinstall the SetUpMasmBasic
there is an alinement issue in that to get the pull down context menu (eg from File) - the cursor has to be in the right adjacent "Tab Setting" (refer attachment - the green "crosshairs" show where the cursor has to be to access File options)
Quote from: Richard on March 27, 2021, 06:33:24 AM
Thanks for [Ctrl] mouse wheel Tip - very helpful for me (eventually will try out template situation).
Now as long as I remember to use [Ctrl] mouse wheel I should be OK (in general)
When you press Alt Z, you can make your level of zooming permanent.
Quotethe top row menu options File Edit&Format etc is not permanently visible (sometimes the case)
They should be visible when the window is activated. Can you check that, please?
Quoteonce I have opened an .asc file (etc) (yellow background) - I cannot seem to be able to get back to the "opening screen" (green background) UNLESS I just reinstall the SetUpMasmBasic
- The green background is reserved for the help file ("opening screen"). You can open it from menu File/MasmBasic help.
- Use menu File/New Masm source to create a new project; use the links with white background for the time being.
- When you hover with the mouse over a keyword such as Print, Open, For_ etc, the cursor turns into an arrow with a question mark; right-click to get a greenish box from which you can copy entire snippets.
- there are many keyboard shortcuts (see \Masm32\MasmBasic\Res\Keywords.ini); try typing
.rep<space> or
opi<space>. You will often need
deb4<space> to understand what your code does.
Quotethere is an alinement issue in that to get the pull down context menu (eg from File) - the cursor has to be in the right adjacent "Tab Setting" (refer attachment - the green "crosshairs" show where the cursor has to be to access File options)
Sorry for that. My noteback has a modest 1366*780 resolution, so I cannot compete with your 3200 x 1800 native display. Aligning the menus was tricky, so I can't promise anything in the near future. The same applies for other elements that are not DPI aware, such as the bookmarks to the right.
@jj2007
Quote
Quote
the top row menu options File Edit&Format etc is not permanently visible (sometimes the case)
[
They should be visible when the window is activated. Can you check that, please?
IF I (left or right) Click in the
" File Edit ... AutoCode" region lets call this region = "..." here and call this clicking = "stray mouse click"
then "..." disappears BUT returns again IF I immediately "valid mouse click", with or without moving mouse!
So as long as I do not "stray mouse click", but "hover" instead, then that stops the disappearing (of course, as mentioned by you, if I go to another application meaning RichMasm is not active = "..." disappear but returns immediately when click in RichMasm background to make RichMasm active)So NOT really a problem of disappearing "..." , just only needs a bit of getting used to (as all other applications I use NEVER disappear their "..." region for "stray mouse clicks" in the "..." region, also other applications never disappear "..." when temporarily leaving but application still visible in multi window)
Thanks for your explanation.
Just getting some practice before I start writing my own code. I tried the following example (first time for examples) and F6 gave the following error.
I may have some residual MASM5.1 (and more recently MASM 6) stuff floating around - so before I start changing/deleting things I better ask! Note that ALL my MASM5.1 (+ MASM 6) stuff existed before I ever heard about RichMasm and MASM32 SDK.
*** Start C:\Masm32\MasmBasic\Res\bldallRM.bat ***
*** 32-bit assembly ***
*** Assemble, link and run SkelTimer ***
*** Assemble using ml ***
Assembling: tmp_file.asm
##########################
You CANNOT use the MasmBasic library with
the old ml.exe version 6.14 - use UAsm instead
##########################
*** MasmBasic version 18.02.2021 ***
*** Warning: SQWORD is unsigned with ml **
\masm32\MasmBasic\MasmBasic.inc(728) : error A2052: forced error
TestMasmVersion(8): Macro Called From
\masm32\MasmBasic\MasmBasic.inc(728): Include File
*** Assembly error ***
Hi Richard,
how did you force RichMasm to use ML? With OPT_Assembler ml? The error message is clear, MasmBasic won't accept the old assembler, for good reasons. So if \Masm32\bin\ml.exe is an old version, you get that message.
By default, RichMasm wants ?:\Masm32\bin\UAsm64.exe, but with e.g. ; OPT_Assembler AsmC you can work with another one.
Do you have the latest UAsm, see http://www.terraspace.co.uk/uasm.html#p2, to be extracted as \Masm32\bin\UAsm64.exe?
I have no experience with any pre-MASM 6.14 code, can you post a short example? Perhaps I can make it run...
@jj2007
Thanks for reply - would have answered sooner (for some reason your email ended up in junk mail and so did not know).
Refer attachment
All I wanted to do was to try programs from the forum (refer last two images) to gain a bit of practice (with code that works) before trying out my original code.
(Keeping in mind that I am still getting used to my 3200x1800 display in high DPI mode (scaling 100) and as you mentioned only some parts I can scale up (to be readable) with Ctrl Mouse wheel but system fonts can not be. So the "mixed sizes" is OK (needs getting used to) but until I practice a lot more, it is easy for me to accidently click in error. Also, I am getting used to selection from top menu bar is not aligned to context columns (as you acknowledged earlier - it is very tricky to code especially when one (you) does not have a high DPI display.
First, just for fun, I wanted to try out the unicode ascii file program - loaded the .asc file from the forum and pressed F6 (not adjusting any settings or anything). A black DOS-like command screen appeared and a little pop-up window saying something to the effect that if some unicode characters do not appear correctly ... then to try Lucinda Console (or something similar sounding). So I immediately went to Settings>Personalize>Fonts> and selected Lucinda Console. I returned to the unicode program console window - but it looked like something "locked up" with it - so I tried to completely close down the program (and RichMasm) but no response. Not even Windows Task Manager OR Task Bar could close it! I could not even move that window around (out of the way of other applications running). "a.asc" was just a temporary "save" just to allow from earlier on, to close RichMASM application - I was not actually wanting to do anything with a.asc - just to close off RichMASM (I got confused with something earlier - so best to start with a "clean slate"). RichMASM locked up with the first image window (keep in mind I was trying to click my way out - so who knows what I may have triggered off.
So I SHUTDOWN my computer, checked that the Lucina Console font was active (according to windows), launched RichMASM and opened up Unicode_File_Names.asc and so the Unicode_File_Names.asc appeared to work OK (just pressing F6 in RichMASM IDE).
I went to the second example program SkelTimer.asc and pressed F6 and the error message as above appeared.
So the "lock up" confused me, I probably did some wrong key presses trying to exit. (I think maybe changing the font and not restarting first also added to the confusion).
I was not attempting to load any old MASM (5 and 6) stuff - however they are still lingering around (maybe I should permanently remove - since I am no longer using DOSBOX and MASM5.1 (RichMASM has "spoilt me")). However it is quite possible that some directories (eg MASM) is loaded up with MASM5.1 stuff and MASM32 SDK stuff etc (I have not checked out for this double useage of directory).
I hope you have enough info from me to see what went wrong - I do not think there is anything wrong with RichMASM.
Hi Richard,
I can't solve the font problems for anything outside the main editor window (listbox, Find+Replace, bookmarks etc) for the time being. Regarding the main editor window, you already know the mouse wheel trick, and I suppose you hit Alt Z to save the zoom level. One more hint: There are templates that use the System font, which is not zoomable; press Ctrl A to select the whole text, then Ctrl L twice. This changes the whole text to a zoomable flavour. Ctrl Shift L selects an extra large text btw - I use that for macro and proc names.
Re freezing: I've experienced that in recent months, and the culprit is Firefox in my case. It happens after a long (5-10 hours) session, and it freezes indeed everything. Normally it goes away after a few minutes. I doubt that RichMasm has any role in it, as its memory usage is tiny compared to a browser.
Thanks a lot for your feedback :thup:
Thanks for reply.
I understand and appreciate re sizes - that is a major reason why I want to "practice" with code that works, so to get "used to" and be "comfortable with" with everything.
I use windows 10 x64 build 2H20 and all sorts of "weird things" quite often happen - the latest is that for a few months now, when I run my computer for a long time (1-3 days continuously) number crunching - I will most likely get a "black screen" , no mater what I try and screen won't come back (and my programs are still running). In these cases I have to press and hold the power key for 10 seconds (the most drastic shutdown procedure).
On this occasion, my computer has been running about 2 days (and the black screen not yet occurred) - so maybe changing the font really really messed up windows).
I will "sleep over it" and start from scratch re example programs before I will download any UASM stuff (I am not planning on going "backwards" (from RichMASM) so after a lot more practice with examples from this forum and RichMASM then will try my own code writing solely using your IDE and F6.
Just a side note, if you don't mind me asking, are you "in the know" about - GNU gcc, Intel syntax versus AT&T syntax, Geany. The reason why I ask is that once I get relatively small and simple sounding MASM projects up and going (in RichMASM) - that I will port the code into a (other) High level language via include files but the preferred way is via gcc and at that using intel syntax (my ultimate aim, the "other" high level language occupies 99% of code but that code only does 1% of the work, the assembly code (technically not really "in-line assembly") occupies 1% of the code but does 99% of the work (and probably much faster))
Quote from: Richard on April 05, 2021, 02:52:37 AMJust a side note, if you don't mind me asking, are you "in the know" about - GNU gcc, Intel syntax versus AT&T syntax, Geany. The reason why I ask is that once I get relatively small and simple sounding MASM projects up and going (in RichMASM) - that I will port the code into a (other) High level language via include files but the preferred way is via gcc and at that using intel syntax (my ultimate aim, the "other" high level language occupies 99% of code but that code only does 1% of the work, the assembly code (technically not really "in-line assembly") occupies 1% of the code but does 99% of the work (and probably much faster))
That's a matter of taste. I don't like C/C++, and I can produce what I need much faster with Basic syntax. I've tried FreeBasic, but it's an awful mess of "toolchains" and "backends", and on the FB Forum 90% of the discussion is about problems compiling some code with the Gas, Gcc, whatever backend. No thanks. In Assembly, the number of instructions is limited, and the machine does exactly what I tell it to do :cool:
Try doing this in C or C++ (you can drag a .txt, .asm, .rtf or .asc file over the exe):
GuiParas equ "Controls", xr20, w500, h200, icon Info, bBlue, m7
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyEdit, "RichEdit", wCL$()
GuiControl MyStatus, "statusbar", "Hello"
Event Command
If_ NotifyCode==BN_CLICKED Then SetWin$ hMyStatus=Str$("Button or menu #%i clicked at ", MenuID)+fTime$(0)
GuiEnd
After exactly one year, MasmBasic was updated today (http://masm32.com/board/index.php?topic=94.0). Inter alia, the StackWalk and profiling macro (http://masm32.com/board/index.php?topic=9854.msg108113#msg108113) might be interesting for members with somewhat bigger projects.
Version 20 February (http://masm32.com/board/index.php?topic=94.0) has one small change against version 18 February:
- with e.g. Declare SomeFunction, 2 passing a string and an immediate as in SomeFunction("Test", 123.456)
will pass a REAL4 as second argument; to force a double, use SomeFunction("Test", REAL8:123.456)
In the new versions, the editor RichMasm has built-in profiling:
- press F9
- hold Ctrl
- click "No"
Version 12 March is online, now with almost 500 commands.
GuiParas equ "Rtf viewer", w700, h600, m0, b none, icon Butterfly ; position, margins, background colour
include \masm32\MasmBasic\Res\MbGui.asm
GetFiles *.as?|*.rtf|*.inc ; load whatever fits your needs
SortFiles name ; could be also date (recent on top) or size (big ones on top)
GuiControl MyList, "listbox", Files$(), x=1000-120, w=0+120 ; leave some space to the right
GuiControl MyEdit, "RichEdit", FileRead$(Files$(0)), bcol RgbCol(120, 120, 120), fcol White, w1000-120, font -14:FW_SEMIBOLD
GuiControl MyStatus, "statusbar", wRec$("Started "+fTime$())
Event Command
.if NotifyCode==LBN_SELCHANGE
SetWin$ hMyEdit=FileRead$(LbSel$) ; load selected file into the RichEdit control
SetStatus$ Cat$("Current file: "+LbSel$+Str$(", %i bytes", LastFileSize)+", created "+GfDate$(-1))
.endif
GuiEnd
Among the improvements is the option to give a foreground colour also to a RichEdit control (see attached source and exe):
GuiControl MyEdit, "RichEdit", FileRead$(Files$(0)), bcol RgbCol(120, 120, 120), fcol White,
This is a tricky business, because it works fine with a plain text file loaded into the RichEdit control, but what about RTF files? They have their own text colours stored in the file, but they don't have a background colour unless you explicitly apply it in your RTF editor, such as RichMasm (http://masm32.com/board/index.php?topic=5314.0) or WordPad.
So what happens is that you tell the control "I want white text on dark background", and that works fine for plain text, but if you load a RTF file, you are stuck with the text colours chosen by the file's author. Which might be, ehm, black... :cool:
Btw the RichEdit control checks automagically if an MS Office versions of RichEd20.dll is installed on your machine. If so, it loads RTF files a factor 20-30 faster than the standard RichEd20 in Windows\System32. That doesn't matter if your files are tiny, but when they approach the megabyte range, it surely makes a big difference. The RichMasm source, for example, with 1.4 MB, loads in less than a second on my trusty old Core i5.
You don't need MS Office to get the fast DLLs: the old Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint (https://filehippo.com/download_microsoft_office_compatibility_pack_for_word_excel_and_powerpoint_file_formats/) installs them for free. Same for the Word viewer (https://filehippo.com/download_word-viewer/), I suppose.
Test it yourself: Extract the exe to a folder that has both *.rtf (or *.asc) files and plain text, such as *.asm and *.inc.
Hi JJ!
Too much talk. What you maked?
Quote from: HSE on March 12, 2022, 02:53:19 PM
Hi JJ!
Too much talk. What you maked?
What did I do to make the fcol White work?
- SetWin$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1092) checks if the control is a RichEdit control (GuiControl (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1304) can be almost every Windows control)
- if so, it checks for the \rtf string at the start of the file to be read in
- if it's plain text, it sends an EM_SETCHARFORMAT message
Then there is a MbLoadRich proc that checks for the presence (in this order) of...
- RichEd20.dll in the executable's folder
- %CommonProgramFiles%\Microsoft shared\Office11\RichEd20.dll
- %CommonProgramFiles%\Microsoft shared\Office12\RichEd20.dll
- %WinDir%\System32\RichEd20.dll
You can force another version using mov RichEditUsed, <path>, and you can check which version was used with a...
MsgBox 0, RichEditUsed, "Your Dll:", MB_OK... before the Event Command (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1395). Simple, right? It can be even simpler; this is a full-fledged rtf viewer in three lines (see CL$() (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1011)):
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyEdit, "RichEdit", FileRead$(CL$()), bcol Black, fcol White
GuiEnd
:thumbsup: Thanks.
I'm developing a different approach for small files.
MasmBasic version 11 May 2022 is online (http://masm32.com/board/index.php?topic=94.0). Mostly minor cosmetics, but there are also some significant changes under the hood:
1. Str$(someDword) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1186) has become blazingly fast, see The joy of beating the CRT by a factor 10 (http://masm32.com/board/index.php?topic=10037.0) in the Laboratory.
2. Same for Instr_(haystack, needle) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153) - it beats the Boyer-Moore algos now most of the time (http://masm32.com/board/index.php?topic=10040.msg109942#msg109942) (and CRT strstr by a factor 10) :cool:
3. MasmBasic's editor RichMasm (part of the package) now supports Hutch' brand new Masm64 SDK (http://masm32.com/board/index.php?topic=10052.0). Just open a source, e.g. \Masm64\Examples\Advanced\JpgTool\JpgTool.asm and hit F6 :thumbsup:
Feedback please, I need to know when things don't work :biggrin:
P.S.: I made some minor changes today. You have the correct version if the zip file is named SetupMasmBasic11May.zip, and there is a link to the Masm64 SDK in the MasmBasic help file at the top of the second "Hello World" example:
include \masm32\MasmBasic\Res\JBasic.inc ; instead of JBasic, you might try the Masm64 SDK
MasmBasic version 20 May 2022 is online (http://masm32.com/board/index.php?topic=94.0). Significant changes:
- RichMasm handles better the case that you "forgot" an active program, e.g. by not answering to an Inkey ("hit any key"); it will present a MessageBox asking if you want to kill the current instance before building the new version.
- improved cycle count macros:
include \masm32\MasmBasic\MasmBasic.inc
Init
CyCtInit
CyCtStart
fldpi
fmul FP8(100.0)
fdiv FP4(10.0)
fstp st
CyCtEnd PI*100/10 ; describe what the code does
EndOfCode
- output is e.g. 17 Cycles for PI*100/10
- without description after CyCtEnd, 1,000 individual cycle counts are accessible through the CyCt() DWORD array
- using CyInit store, the counts are saved to the CyCt$() array (see Store (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1174) for saving the array to disk)
Version 30 May 2022 is online, with several minor improvements, inter alia of NoTag$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1077)():
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
FileWrite "test.tab", NoTag$(Clip$()) ; get html from the clipboard, convert to plain text
ShEx "test.tab" ; launch the application associated with *.tab (often Excel)
EndOfCode
Source & exe attached. To test it,
- go to a site that has tables, e.g. https://www.tiobe.com/tiobe-index/ or http://masm32.com/board/index.php?action=stats
- press Ctrl U to see the html source
- press Ctrl A, Ctrl C to copy the source
- launch the attached executable
The output file test.tab will open e.g. in Excel. On my machine, it will look like this:
(https://www.jj2007.eu/pics/HtmlTableFromClipboard.png)
As you can see, row #5 is slightly off - sometimes the tab files may require some editing. Another example, exported from https://www.stackscale.com/blog/popular-programming-languages-2021/ and imported into M$ Excel:
(https://www.jj2007.eu/pics/HtmlTableFromClipboard2.png)
I attach a sample tab file extracted from WorldoMeters (https://www.worldometers.info/co2-emissions/co2-emissions-per-capita/). Most Wikipedia tables should work, too - please inform me if you find one that doesn't. Note it will not work on sites that use scripts to generate tables, such as this World Bank page (https://data.worldbank.org/indicator/EN.ATM.CO2E.PC).
The ancient Internet Explorer used to have the option to export a table; no idea why they abolished it :cool:
Version 2 October is online (http://masm32.com/board/index.php?topic=94.0) :biggrin:
It's over 500 macros now. Here are the additions since November 2020:
SetLaunchEnvironment
Ini$
Cls
_Passed$
Arctangens
rTangens
Tangens
rCotangens
Cotangens
ArcSinus
rArcSinus
Cosinus
rCosinus
Tangent
FontExist
WinByClass
WinFromID
WinFromID$
MbProfile
WarmUp
CyCtInit
CyCtStart
CyCtEnd
SetWatch
swShow
swEnd
StackWalk
SWalkP
SWalkE
@FP4
@FP8
@FP10
GuiImageSet
With a handful of exceptions, they are documented in \Masm32\MasmBasic\MbGuide.rtf; search e.g. for .MbWinByClass
The most recent addition are coloured pushbuttons:
GuiParas equ "Colourful buttons", w320, h110 ; 32% of window width, 11% of height
; GuiButtonPen equ <MakePen MbBtnPen, RgbCol(128, 255, 255, 255), width 3> ; white, half transparent
include \masm32\MasmBasic\Res\MbGui.asm ; select GuiParas and hit F6
GuiControl Button1, "button", "That's a normal pushbutton", w250, h0+40 ; width 25% of client area, height 0%+40px
GuiControl Button2, "button", "Lite Turquoise"/"Blue", bcol LiteBlueGreen/Blue, x250, w250, h0+40, font -14
GuiControl Button3, "button", "Lite Yellow"/"Full Yellow", bcol LiteYellow/Yellow, fcol Red/Black, x500, w250, h0+40, font -14:FW_BOLD
GuiControl Button4, "button", "Rounded button", bcol LiteGrey/Red, fcol Black/White, rr40, x750, w250, h0+40, font -12:FW_SEMIBOLD
GuiEnd
Rem To define a button, use:
- x, y, w, h for its position, followed by n 1000th of the window width or height
- bcol RgbCol(...) to define the background colour; bcol Blue/Red means "blue, but red if pressed"
- fcol Black/White to define the foreground (text) colour; white if pressed
- "normal text"/"pressed text"
- rr0=no rounded corners, rr100=a circle; use guiRoundRect=n to set the default rounding
- you may define a pen: put GuiButtonPen before the include line
With 7 lines of code, you can create this:
(http://www.jj2007.eu/pics/ColouredButtons.png)
These buttons require an XP manifest, as shown in the attachment. When you size the window, the buttons size horizontally but not vertically, due to the w250, h0+40.
If you zoom in the image below, you may notice that the buttons' borders use antialiasing: under the hood, Gdi+ is at work.
MasmBasic version 15 Nov 22 is online (http://masm32.com/board/index.php?topic=94.0). The included RichMasm editor will now colourise plain text asm sources to a certain extent, like in this example from \Masm32\examples\threads\multhread\multhrd.asm:
WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL tID :DWORD
Switch uMsg
Case WM_COMMAND
Switch wParam
Case 50
; ------------------------------------
; loop through starting 10 new threads
; ------------------------------------
push esi
push edi
xor esi, esi
xor edi, edi
@@:
add esi, 25
add edi, 1
fn CreateThread,0,0,ADDR CreateNewThread,esi,0,ADDR tID
cmp edi, 10
jl @B
pop edi
pop esi
Case 51
; ----------------
; close all thread
; ----------------
All push arg and pop arg instructions are highlighted in red. Jumps to @@: labels are red for @B and blue for @F. Such a few red spots can help to recognise, for example, problems with stack balance. I am not a fan of Christmas trees aka automatic highlighting of each and every little feature, but I do use manual colouring in my sources, especially when doing little tricks, see below.
When saving the source code in RTF format (as *.asc), these changes are permanent.
Install the latest MasmBasic version (http://masm32.com/board/index.php?topic=94.0) to get access to over 500 powerful macros, and in case you want to build the Simple Editor (http://masm32.com/board/index.php?topic=10401.msg116252#msg116252). Latest items:
Guid$():
Let edi=Guid$()
MsgBox 0, Cat$("A Guid: ["+edi+"]"), "Hi", MB_OK
Output: A Guid: [d6e3dc8a-f76a-4ec2-9163-65f8bdd0138f] (plus a pointer to the GUID itself in edx)
xCall for passing arguments to a label, invoke style:
include \masm32\MasmBasic\MasmBasic.inc
.code
somelabel:
mov ecx, [esp+4]
MsgBox 0, ecx, "Hi", MB_OK
retn 4
Init
xCall somelabel, Chr$("Hello World")
EndOfCode
MsgBox: see http://masm32.com/board/index.php?topic=10530.msg116251#msg116251, the new MsgBox will not make your controls lose the focus.
I forgot this one: CenterWindow hWnd_, 400, 200 ; 400px wide, 200px high, right in the middle
Quote from: jj2007 on December 06, 2022, 11:18:30 AM
Install the latest MasmBasic version (http://masm32.com/board/index.php?topic=94.0) to get access to over 500 powerful macros, and in case you want to build the Simple Editor (http://masm32.com/board/index.php?topic=10401.msg116252#msg116252). Latest items:
Guid$():
Let edi=Guid$()
MsgBox 0, Cat$("A Guid: ["+edi+"]"), "Hi", MB_OK
Output: A Guid: [d6e3dc8a-f76a-4ec2-9163-65f8bdd0138f] (plus a pointer to the GUID itself in edx)
xCall for passing arguments to a label, invoke style:
include \masm32\MasmBasic\MasmBasic.inc
.code
somelabel:
mov ecx, [esp+4]
MsgBox 0, ecx, "Hi", MB_OK
retn 4
Init
xCall somelabel, Chr$("Hello World")
EndOfCode
MsgBox: see http://masm32.com/board/index.php?topic=10530.msg116251#msg116251, the new MsgBox will not make your controls lose the focus.
Hi jj2007,
Bad DLL for R? - msftEdit.dll
Hi LiaoMi,
On my Win7-64, C:\Windows\System32\msftedit.dll accepts only RichEdit50W RichEdit60W as well as RichEdit20W. Which Windows version are you running?
Can you do me favour and test the attached version, which does an extra check? If you get it running, please hit F9 and give me the RichEdit??W version. Thanks :thup:
My windows 7 x64 msftedit use RichEdit50W
File version: 5.41.21.2510
Inside dll is UNICODE string RichEdit50W
Quote from: TimoVJL on December 08, 2022, 10:07:29 AM
My windows 7 x64 msftedit use RichEdit50W
File version: 5.41.21.2510
Inside dll is UNICODE string RichEdit50W
RichEdit is driving me mad!
00000000 RichEdit20W
Impossibile trovare la classe della finestra.
001603E0 RichEdit50W
Operazione completata.
00000000 RichEdit60W
Impossibile trovare la classe della finestra.
00000000 RichEdit20A
Impossibile trovare la classe della finestra.
00000000 RichEdit50A
Impossibile trovare la classe della finestra.
Fun fact: RichMasm.exe runs just fine with
RichEdit60W... and I just found out why - it loads the Office12 variant present on my machine :rolleyes:
Testbed attached, pure Masm32 SDK :cool:
Quote from: jj2007 on December 08, 2022, 08:41:34 AM
Hi LiaoMi,
On my Win7-64, C:\Windows\System32\msftedit.dll accepts only RichEdit50W RichEdit60W as well as RichEdit20W. Which Windows version are you running?
Can you do me favour and test the attached version, which does an extra check? If you get it running, please hit F9 and give me the RichEdit??W version. Thanks :thup:
Hi jj2007,
I have windows 10 Ent 21h1 :rolleyes:
---------------------------
RichMasm editor version 07.12.2022, built with UAsm64:
---------------------------
RichEdit20W of msftEdit.dll, ComCtl32 version 6.16
---------------------------
Yes No Cancel
---------------------------
Thanks a lot, LiaoMi :thup:
Well MasmBasic (3March23) installed okay. But upon running RichMasm:
'Compatibilty Options' (Exporer Right Click) did nothing to help resolve this. AVX code there I suppopse?
No AV software btw.
Have a recommendation for previous version that *might* work for me here?
Attached image removed as it has served its purpose.
Quote from: zedd151 on June 21, 2023, 03:35:20 AM
Well MasmBasic (3March23) installed okay. But upon running RichMasm:
'Compatibilty Options' (Exporer Right Click) did nothing to help resolve this. AVX code there I suppopse?
No AV software btw.
Have a recommendation for previous version that *might* work for me here?
This is the SSE 4.2 problem, sorry. Can you please run the attached test?
Thanks for the reply. Not really urgent for me, was only going to play around with it for a bit - but for compatibility for other users might be a good idea at least to have a separate (dumbed down lol) version for users with same CPU issues ( old as dirt computer/CPU that is) and still keep the presumably high powered version for users with more modern hardware.
Quote from: jj2007 on June 21, 2023, 04:18:47 AM
Can you please run the attached test?
Old cpu
MessageBox:
eax 7139135
:cool:
Ok, bug found. It is more complicated than I thought, though. Please extract the attached exe as \Masm32\MasmBasic\RichMasm.exe and launch it. That should work fine, but it's a debug edition.
Quote from: jj2007 on June 21, 2023, 06:09:32 AM
That should work fine, but it's a debug edition.
Yerp, it appears to be working alright.
Building an example there prompts to install Uasm64? hrumph ... okay I see the examples in Masm64 folder. lol I don't have Masm64 on this OS, its 32 ... :biggrin:
Quote from: jj2007 on June 21, 2023, 06:29:39 AM
It expects to find \Masm32\bin\uasm64.exe
Well crap. Lemme through 64 bits into another partition.... will only take a few minutes ...
Okee dokee Windows 10- 64 is being installed as I speak... takes a while longer than plonking a fresh copy of Windows 7 into the box.
You install Win10? That's an overkill, my friend...
No need for a Masm64 folder, it works fine with what you have already. However, it expects \Masm32\bin\UAsm64.exe, and I just see that you have a 32-bit OS :rolleyes:
Solution: make a copy of your UAsm32.exe and call it UAsm64.exe :cool:
https://www.terraspace.co.uk/uasm.html#p2 is the download link, in case you don't have UAsm at all. You need the 32-bit version, and it must be renamed to UAsm64.exe to work. That's a bug or a missing feature with RichMasm, because I haven't seen a 32-bit Windows version for quite some time ;-)
Yup, I install w10 (from disk image backup) only when needed. I cannot find atm the image for 7/64... :biggrin:
Had to go and walk the dog while reinstalling Win 10. But I got er done. :biggrin:
Aw, c'mon now... polink??? :tongue: Lemme fetch a copy :rolleyes:
Alright everything is working okay here now. :biggrin: If I can only remember now, what file I wanted to look at that was a MB (asc) source. :tongue:
RichMasm seems a bit 'busy' for my taste - btw.
I am going to make a backup copy (of the partition) with the MasmBasic Dev environment set up in it. Just in case the need for it ever arises. I know that at times, you post some interesting sources... now I'll head back over to Windows 7 :cool:
Okay, now I am back on Windows 7 :biggrin: . How would I configure RichMasm to better suit my needs, as far as appearance, fonts, etc?
- For fonts, check FaceSrc=... etc in \Masm32\MasmBasic\Res\RichMasm.ini (may be overwritten at next install, so save a copy)
- You can zoom the font with Ctrl + mousewheel. Save your setting with Alt Z
- Press Ctrl G, then type behind the Goto: prompt udc=n, where n=0...9
Quote from: zedd151 on June 21, 2023, 07:18:50 AMRichMasm seems a bit 'busy' for my taste
I don't understand - what do you mean?
Quote from: jj2007 on June 21, 2023, 09:58:50 AM
- For fonts, check FaceSrc=... etc in \Masm32\MasmBasic\Res\RichMasm.ini (may be overwritten at next install, so save a copy)
Oh, there's an ini file. I missed that. I'll take a look at this later...
Hi Z,
New version (http://masm32.com/board/index.php?topic=94.0) should fix all your issues:
- accepts \Masm32\bin\UAsm32.exe
- uses the old Instr() algo if the Cpu is below SSE 4.2
Plus, it has a new macro (heavily inspired by NoCForMe - thanks :thup:):
DrawMyRect proc hDC
Local hBrush, whatever
CreateAndSelect(hDC) ; one arg: set the DC (right after the locals)
mov hBrush, CreateAndSelect(brush, Blue) ; the hBrush is not really needed
invoke Rectangle, hDC, 3, 3, 202, 78
void CreateAndSelect(brush, LiteYellow)
invoke Rectangle, hDC, 9, 9, 196, 72
invoke SetBkMode, hDC, TRANSPARENT
casThrowErrors=1 ; now try bitmap instead of font v v v
void CreateAndSelect(font, addr MyFont)
invoke TextOut, hDC, 20, 18, fTime$(), 9
ReleaseObjects ; no leaks please ;-)
ret
DrawMyRect endp
First argument of CreateAndSelect can be bitmap, brush, font or pen (case-insensitive).
Project attached.
Quote from: jj2007 on June 24, 2023, 11:25:51 PM
Hi Z,
New version (http://masm32.com/board/index.php?topic=94.0) should fix all your issues:
Project attached.
You really didn't have to, but thanks. As said before I will look at MasmBasic later on, when I have enough time to delve in to the macros there and other 'masm basic' specifics. It's like learning a new language (probably like Mandarin :greensml: ) either way it's mostly Greek to me at this point. Will take some time... :cool:
Quote from: jj2007 on June 24, 2023, 11:25:51 PM
Project attached.
57 kb example exe? :dazzled: How big is the runtime library contained within? :tongue:
It works as advertised of course, and no leaks. Surely I have adequate memory for this behemoth example. :biggrin:
Quote from: zedd151 on June 24, 2023, 11:46:07 PMIt's like learning a new language
It
adds macros and routines to Masm32. Practically all the sources in \Masm32\Examples build fine by simply hitting F6 in RichMasm. It's a bit like moving from "old" assembly to SIMD assembly - you add new features.
Quote from: zedd151 on June 24, 2023, 11:50:11 PM
Quote from: jj2007 on June 24, 2023, 11:25:51 PM
Project attached.
57 kb example exe? :dazzled: How big is the runtime library contained within? :tongue:
It works as advertised of course, and no leaks. Surely I have adequate memory for this behemoth example. :biggrin:
\masm32\MasmBasic\Res\MiniWin.asc builds a 34kB exe, which is about the minimum. That's a lot compared to the 1,024 bytes examples, but it also means features such as Recall (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1172).
For comparison, a standalone QT "hello World" is 8MB :cool:
Quote from: jj2007 on June 25, 2023, 12:29:57 AM
For comparison, a standalone QT "hello World" is 8MB :cool:
:rofl: okay, good point. :biggrin:
Still, it will take me some time to digest all of the 'new' things there. In due time...
I've installed the latest version of MasmBasic (I thought I'd never say that again :tongue: ) , Uasm and put polib back into the bin folder.
Succesfully assembled an example from Masm32 SDK examples. :thumbsup:
'Select proc or macro' does
not select proc or macro. :tongue: I wanted to see that work, since you had mentioned that recently.
Quote from: jj2007 on June 22, 2023, 03:50:50 AM
Quote from: zedd151 on June 22, 2023, 12:48:48 AMto right click a selected procedure name anywhere in the source and click 'go to procedure' or 'select procedure'.
I can confirm that this is a very useful feature
Quote from: zedd151 on June 25, 2023, 12:35:18 AM'Select proc or macro' does not select proc or macro
You must select the word
proc or the word
macro, then you right-click.
Another minor "bugfix" (it's not a bug, actually) concerning Instr_(haystack, needle) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153):
.if Instr_(esi, "test")
...
That always worked fine. However, the old "below SSE 4.2" algo returned, if nothing was found, a pointer in eax. So, if you were clever and used, for some odd reason...
void Instr_(esi, "test")
.if eax
...
... that gave the wrong answer, because the found/not found is being returned in edx, while eax points at the result if one is found. In the previous version, eax pointed at haystack-1 if nothing was found, so .if eax failed. I fixed it, now eax is zero for no match.
Quote from: jj2007 on June 25, 2023, 12:59:04 AM
Quote from: zedd151 on June 25, 2023, 12:35:18 AM'Select proc or macro' does not select proc or macro
You must select the word proc or the word macro, then you right-click.
Okay, only works some of time...
in attached example displays error "not found: endp"
selecting 'proc' for WndProc for example.
edit=removed attachment as it has served its purpose.
I see; it's a coding style issue: you leave four spaces before WinMain proc and WinMain endp. The algo expects
WinMain proc
...
WinMain endp
Sorry, it won't work for you. For consistency, I never leave spaces before the xxx proc or the xxx macro. Inside macros, when there is more than one ENDM, only the last one has no spaces.
Do your 4 spaces serve a specific purpose?
Of course, formatting. I detest hard tabs. :tongue:
okay then, I'll keep this in mind if selecting a procedure or macro comes up in a real situation.
Quote from: zedd151 on June 25, 2023, 01:17:53 AM
Of course, formatting. I detest hard tabs. :tongue:
Tabs or spaces,
what for at the beginning of a proc? That's the central unit in your source, it should be left-aligned imho :cool:
All my procs follow this formatting:
DrawMyRect proc hDC
Local hBrush, whatever
CreateAndSelect(hDC) ; one arg: set the DC (right after the locals)
mov hBrush, CreateAndSelect(brush, Blue) ; the hBrush is not really needed
.if !eax
MsgBox 0, "error", "Hi", MB_OK
.endif
ReleaseObjects ; no leaks please ;-)
ret
DrawMyRect endp
First line, locals, last line: no blanks
Level 1: two spaces
Level n: n tabs
For good readability...
Quote from: jj2007 on June 25, 2023, 01:20:50 AM
Tabs or spaces, what for at the beginning of a proc? That's the central unit in your source, it should be left-aligned imho :cool:
Actuall I haven't the slightes idea why I do it. I had started that practice years ago and the reasoning behind it is lost to history. :rolleyes: Very odd.
Quote from: zedd151 on June 25, 2023, 01:24:26 AM
Quote from: jj2007 on June 25, 2023, 01:20:50 AM
Tabs or spaces, what for at the beginning of a proc? That's the central unit in your source, it should be left-aligned imho :cool:
Actuall I haven't the slightes idea why I do it. I had started that practice years ago and the reasoning behind it is lost to history. :rolleyes: Very odd.
I checked some sources in \Masm32\examples. Hutch did
procs like I do, but left spaces before mytest
macro :rolleyes:
Would this be a good starting point for learning Assembly? Keen to give it a crack!
jj2007's MasmBasic confused the h*ll out of when I first got started with MASM. Sorry jj.
It's a very complicated macro system for doing assembly. "Basic" is becuase it has a Basic
language like syntax.
Quote from: Caché GB on July 06, 2023, 10:28:37 AM
jj2007's MasmBasic confused the h*ll out of when I first got started with MASM. Sorry jj.
:biggrin:
QuoteIt's a very complicated macro system for doing assembly. "Basic" is becuase it has a Basic
language like syntax.
include \masm32\include\masm32rt.inc
.code
start:
print "Masm32 is great"
MsgBox 0, "Hello World", "Basic style", MB_OK
exit
end start
Guess what? This is
not MasmBasic, it's "HutchBasic" aka "Masm32 SDK". I grew up with GfaBasic (https://en.wikipedia.org/wiki/GFA_BASIC), Hutch grew up with PowerBasic (https://en.wikipedia.org/wiki/PowerBASIC). That's one reason why we understood each other very well :tongue:
Re "very complicated macro system": under the hood, yes. For the user, it's actually very simple to do things like
Let esi="Now esi is a pointer to a string", or
include \masm32\MasmBasic\MasmBasic.inc
Init
.if Instr_(FileRead$("\Masm32\menus.ini"), "[&Project")
PrintLine "QEditor has a project section: ", Left$(eax, 200)
.else
PrintLine "Nope, no project section in your QEditor menus"
.endif
EndOfCode
Quote from: StrykerX on July 06, 2023, 10:03:35 AM
Would this be a good starting point for learning Assembly? Keen to give it a crack!
Opinions differ wildly. My extremely biased take on this is that using MasmBasic, you can do everything that you can do with the standard Masm32 libraries
plus deb (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019) and Recall (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1172) and a few (500+) others. Example:
include \masm32\MasmBasic\MasmBasic.inc
Init
mov eax, 12345
cdq
mov ecx, 123
deb 4, "Before the div:", eax, edx, ecx
div ecx
deb 4, "What happened to the registers?", eax, edx, ecx
EndOfCode
Output:
Before the div:
eax 12345
edx 0
ecx 123
What happened to the registers?
eax 100
edx 45
ecx 123
Check the File/MasmBasic help menu in RichMasm:
(http://www.jj2007.eu/pics/MbHelp.png)
MasmBasic (http://masm32.com/board/index.php?topic=94.0) of 26.7.23 features:
- the MbMod macro (https://masm32.com/board/index.php?msg=121943)
- when you select a number in RichMasm and press Ctrl N, the dec, hex & binary representations can be copied to the clipboard.
MasmBasic (http://masm32.com/board/index.php?topic=94.0) of 28.7.23 fixes a minor bug with wStr$(number) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1274): if no format string was present, it spit out Ansi instead of Unicode. Works fine now :thumbsup:
Quote from: StrykerX on July 06, 2023, 10:03:35 AMWould this be a good starting point for learning Assembly? Keen to give it a crack!
Wellll, since you got one biased answer, from the author of MasmBasic, JJ, here's another answer biased in the other direction.
Mind you, I have nothing bad to say about his creation. It's magnificent, a megalithic work, a wonderful system that seems to do everything: macros galore, and it slices and dices.
However, my suggestion would be to learn standard assembly language (MASM) first. Why? Because if you start with MasmBasic, for one thing you'll get spoiled, and if you make a transition to standard MASM you'll probably be disappointed. Plus I think the less insulated approach of standard asm, having to do everything "by hand", may make you understand the underlying principles better.
But you should definitely try it (MasmBasic) at some point.
(My bias here is that I don't even like to use macros with MASM. I'm pretty much a loner here in that regard.)
Quote from: NoCforMe on July 29, 2023, 01:11:10 PMif you start with MasmBasic, for one thing you'll get spoiled
Good point :thumbsup:
For example, by changing five lines in \Masm32\examples\exampl04\jacts\jacts.asm:
if 1
include \masm32\MasmBasic\MasmBasic.inc
uselib winmm ; see deb below
else
.386
.model flat,stdcall
option casemap:none
...
includelib \masm32\lib\winmm.lib
endif ; ----- ^ ^ ^ excluded in favour of MasmBasic -----
... you don't change anything. Oh wait: the executable is 4 times bigger... and you can use the deb macro (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019) from now on ;-)
What's new in MasmBasic version 2 August 2023 (http://masm32.com/board/index.php?topic=94.0)?
a) Coloured rounded ownerdraw buttons, with text that moves some pixels to the right and down when the button is pressed (https://masm32.com/board/index.php?topic=11082.0):
(http://www.jj2007.eu/pics/ColouredButtons.png)
b) the fastest Hex$() (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1198) ever:
Let o$=New$(40000000h)+"END"
REPEAT 5
NanoTimer()
mov edi, o$
xor ebx, ebx
.Repeat
Hex$(ebx, edi)
add edi, QWORD
inc ebx
.Until ebx>=8000000h
Print NanoTimer$(), Str$(" for writing %i MB\n", ebx/1048576)
Output:
315 ms for writing 128 MB
366 ms for writing 128 MB
361 ms for writing 128 MB
310 ms for writing 128 MB
312 ms for writing 128 MB
Same with standard Masm32 SDK hex$() - invoke dw2hex, ebx, edi:
1961 ms for writing 128 MB
1967 ms for writing 128 MB
1940 ms for writing 128 MB
1991 ms for writing 128 MB
1968 ms for writing 128 MB
Not to mention that you can use invoke crt_sprintf, edi, chr$("%00x"), ebx, too - but it takes 26 seconds :biggrin:
Nice looking rounded buttons. Do you use GDI+ or D2D?
Quote from: 2B||!2B on September 10, 2023, 11:32:07 AMNice looking rounded buttons. Do you use GDI+ or D2D?
Thanks. It's Gdi+
MasmBasic & RichMasm were updated (http://masm32.com/board/index.php?topic=94.0): Now most if not all sources in...
\Masm32\Examples
\Masm64\Examples
... will assemble & link out of the box just by hitting F6 in RichMasm. No individual batch file is needed, since the IDE will autodetect if a) resources are needed and b) if it's a console or GUI application.
Please let me know if you find an example does not build flawlessly. Actually, I found one: \Masm64\Examples\Advanced\tEdit\tEdit.asm needs an OPT_Assembler ml64 to build properly, in a comment or at the end of the source (Hutch put the masm64rt.ìnc in an include file instead of the main source...).
Plus minor improvements, such as the icon option for static controls (project attached, it's just two tiny files):
GuiParas equ "Hello Ida", w104, h222, b BlueGreen, style 0, icon Butterfly ; width+height, background colour, icon for caption
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyStatic, "static", icon IDI_APPLICATION
GuiEnd
Rsrc
#include "resource.h"
01 RT_MANIFEST "\\Masm32\\MasmBasic\\Res\\XpManifest.xml"
IDI_APPLICATION ICON "Ida.ico"
Rsrc
You may note that in RichMasm, the resources can be integrated into the main source. This is often handy, as you can edit quickly e.g. a resource ID in both the asm and the rc file without opening two files. When hitting the build button F6, the section between the two Rsrc lines gets exported to [filename].rc before the assembly starts.
I just installed this on the sdk from http://masm32.masmcode.com/masm32/masm32v11r.zip (had to use Edge and bypass the "can't be downloaded securely).
When I click on File / Build and run get :
\masm32\bin\UAsm32' is not recognized as an internal or external command,
operable program or batch file.
*** Assembly error ***
Hi mstram,
Check https://www.terraspace.co.uk/uasm.html#p2 (https://www.terraspace.co.uk/uasm.html#p2)
There are UAsm64.exe and UAsm32.exe. Are you using a 32-bit version of Windows?
Thanks, working now
Update 11 October 2023 (download (https://masm32.com/board/index.php?topic=94.0)):
1. Clean$(pString, leftMatch, rightMatch, mode):
include \masm32\MasmBasic\MasmBasic.inc
Init ; select and hit F6
Let esi="index.php?PHPSESSID=74e64f1f&topic="
PrintLine "before: [", esi, "]"
PrintLine "after: [", Clean$(esi, "PHPSESSID=", "&", 0), "]" ; string, left, right match, mode
EndOfCode
Output:
before: [index.php?PHPSESSID=74e64f1f&topic=]
after: [index.php?topic=]
It's the counterpart to Extract$() (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1156):
- "cleans" a given string depending on left and right matches
- mode as in Instr_()
- if no right match is given, Cr$ is assumed, i.e. until end of line
2. GuiControl allows now to set the background colour with e.g. Ini$() - see CheckNewPosts (https://masm32.com/board/index.php?msg=124449):
.if !Ini$() ; if [filename].ini not found, create it and set defaults:
SetIni$ "upperBgColour", Str$(LiteBlueGreen)
SetIni$ "lowerBgColour", Str$(LiteGrey)
.endif
GuiControl TheDesc, "RichEdit", y=0+26, h=0+230, font -16, bcol <Val(Ini$("upperBgColour"))>, text hover$
GuiControl TheLinks, "RichEdit", y0+228, h1000-228, font -14, bcol <Val(Ini$("lowerBgColour"))>
Update 28 October 23 (http://masm32.com/board/index.php?topic=94.0):
a) ZipFiles adjusted, see here (https://masm32.com/board/index.php?topic=11385.msg124786#new)
b) CoInvoke:
Sometimes you see things like this on the web:
hResult = pISD->namespace(vFile, &pToFolder)
To make the translation to Assembly easier, you can now use
Local vDest:VARIANT
mov vDest.vt, VT_BSTR ; the type
mov vDest.bstrVal, rv(SysAllocStringLen, ecx, eax) ; put a filename
CoInvoke pISD, IShellDispatch.NameSpace, vFile, &pFolder
Looks unnecessary? Yes, but the "v" in vFile stands for VARIANT, and to do that properly by hand, you would need this:
CoInvoke pISD, IShellDispatch.NameSpace, VT_BSTR, 0, vFile.bstrVal, 0, addr pFolder
It's easy to get a little bit confused here, especially if the COM call expects several VARIANTs, as e.g. in Folder.CopyHere :cool:
Update 2 December 23 (https://masm32.com/board/index.php?topic=94.0):
As shown in the Assembly uses Python (https://masm32.com/board/index.php?topic=11506.0) thread, it may happen that a DLL doesn't work as expected because, well, it can't find its components. Python3.dll loads six more DLLs, and since it's a bit dumb, it looks for them
a) in the current folder (i.e. the executable's folder)
b) in C:\Windows\System32
No luck, folks, if the executable sits elsewhere. So I had to invent the SetDllFolder macro:
include \masm32\MasmBasic\MasmBasic.inc
Init
SetDllFolder "\Python" ; adjust to your setup; downloaded from here (https://www.python.org/ftp/python/3.8.9/python-3.8.9-embed-win32.zip)
Dll "python38" ; depends on six more DLLs
Declare void Py_Initialize
Declare void PyRun_SimpleString, C:1 ; requires python38.dll
SetDllFolder ; no args=go back to previous folder after declaring the functions
Py_Initialize()
PyRun_SimpleString("MyLong=123456789") ; use the interpreter
Inkey "ok"
EndOfCode
The good news is that with SetDllFolder you don't need the full path for Dll "Python3" :cool:
Overall, Python is a horrible mess:
- Python 3 is absolutely incompatible with Python 2
- dll hell, see SetDllFolder above
- there is Python3.dll in the downloaded folder (https://www.python.org/ftp/python/3.8.9/python-3.8.9-embed-win32.zip), but it does not pass on all the functions of the main DLL, which is (in this case) Python38.dll
- so you often must hardcode the version in your code, and force the user to install a specific version (3.8 is the last one that works on Win7 btw)
- there are three distinct methods to access Python from Assembly:
1. C API (https://docs.python.org/3/c-api/) (probably the fastest)
2. PyRun_SimpleString
3. PyObject_CallMethod
- my guess is that three quarters of the over 1,600 functions exported by Python38.dll are either for typecasting or simply redundant
Idea for hunting down correct Python3x.dll, but not reliable, as that string is missing many import Python3.dlls, like in version 3.10.0
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
// https://docs.python.org/3/c-api/
typedef void (PY_INITIALIZE)(void);
typedef PY_INITIALIZE *LPPY_INITIALIZE;
// PyRun_SimpleString
typedef int PYRUN_SIMPLESTRING(char *);
typedef PYRUN_SIMPLESTRING *LPPYRUN_SIMPLESTRING;
int __cdecl main(void)
{
static LPPY_INITIALIZE Py_Initialize;
static LPPYRUN_SIMPLESTRING PyRun_SimpleString;
char szVersion[50];
char szPythonDll[260] = "bin64/Python3.dll";
HMODULE hMod = LoadLibrary(szPythonDll); //
if (hMod) {
int nLen = GetModuleFileName(hMod, szPythonDll, 260);
LoadString(hMod, 1000, szVersion, 50);
printf("%s\n", szVersion);
FreeLibrary(hMod);
szPythonDll[nLen-5] = szVersion[0];
szPythonDll[nLen-4] = szVersion[2];
szPythonDll[nLen-3] = 0;
printf("%s\n", szPythonDll);
hMod = LoadLibrary(szPythonDll);
}
if (hMod) {
printf("%s loaded\n", szPythonDll);
Py_Initialize = (LPPY_INITIALIZE)GetProcAddress(hMod, "Py_Initialize");
if (Py_Initialize) {
Py_Initialize();
PyRun_SimpleString = (LPPYRUN_SIMPLESTRING)GetProcAddress(hMod, "PyRun_SimpleString");
if (PyRun_SimpleString) {
PyRun_SimpleString("print('Python Print test')");
} else printf("PyRun_SimpleString not found\n");
} else printf("Py_Initialize not found\n");
FreeLibrary(hMod);
} else printf("Python3x.dll not loaded\n");
return 0;
}
This works with 3.10
char szVersion[50];
char szPythonDll[260] = "bin64_310/Python3.dll";
HMODULE hMod = LoadLibrary(szPythonDll);
if (hMod) {
int nLen = GetModuleFileName(hMod, szPythonDll, 260);
printf("%s\n",GetVersionInfo(hMod, "FileVersion", szVersion, sizeof(szVersion)));
FreeLibrary(hMod);
szPythonDll[nLen-5] = szVersion[0];
szPythonDll[nLen-4] = szVersion[2];
if (szVersion[3] != '.') szPythonDll[nLen-3] = szVersion[3]; else szPythonDll[nLen-3] = 0;
szPythonDll[nLen-2] = 0;
printf("%s\n", szPythonDll);
hMod = LoadLibrary(szPythonDll);
}
GetVersionInfo.c
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winver.h>
#include <stdio.h>
#pragma comment(lib, "version.lib")
#pragma comment(lib, "user32.lib")
LPSTR GetVersionInfo(HMODULE hMod, TCHAR *szValue, TCHAR *szBuffer, ULONG nLength)
{
LPSTR csRet;
csRet = NULL;
HRSRC hVersion = FindResource(hMod, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
DWORD dwSize = SizeofResource(hMod, hVersion);
if (hVersion != NULL)
{
HGLOBAL hGlobal = LoadResource(hMod, hVersion);
if (hGlobal != NULL)
{
//LPVOID ver = LockResource(hGlobal);
LPVOID ver = LocalAlloc(LPTR, dwSize*2);
if (ver != NULL)
{
memcpy(ver, hGlobal, dwSize);
DWORD *codepage;
UINT len;
char fmt[0x40];
PVOID ptr = 0;
if (VerQueryValue(ver, "\\VarFileInfo\\Translation", (LPVOID) & codepage, &len))
{
//wsprintf(fmt, "\\StringFileInfo\\%04x%04x\\%s", (*codepage) & 0xFFFF, (*codepage) >> 16, csEntry);
wsprintf(fmt, "\\StringFileInfo\\%08x\\%s", (*codepage) << 16 | (*codepage) >> 16, szValue);
if (VerQueryValue(ver, fmt, &ptr, &len))
{
lstrcpyn(szBuffer, (TCHAR*)ptr, min(nLength, len));
csRet = szBuffer;
}
}
LocalFree(ver);
}
FreeResource(hGlobal);
}
}
return csRet;
}
EDIT 2023-12-03:
api-ms-win-core-path-l1-1-0.dll for Windows 7 (https://github.com/nalexandru/api-ms-win-core-path-HACK)
Windows API function AddDllDirectory() is useful with
LoadLibraryEx(szPythonDll, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
char szVersion[50];
char szPythonDll[260] = "bin64_310/Python3.dll";
wchar_t wszPath[260];
HMODULE hMod = LoadLibrary(szPythonDll);
if (hMod) {
int nLen = GetModuleFileNameW(hMod, wszPath, 260);
while (wszPath[--nLen] != '\\');
if (nLen) wszPath[nLen+1] = 0;
AddDllDirectory(wszPath);
nLen = GetModuleFileName(hMod, szPythonDll, 260);
printf("%s\n",GetVersionInfo(hMod, "FileVersion", szVersion, sizeof(szVersion)));
FreeLibrary(hMod);
szPythonDll[nLen-5] = szVersion[0];
szPythonDll[nLen-4] = szVersion[2];
if (szVersion[3] != '.') szPythonDll[nLen-3] = szVersion[3]; else szPythonDll[nLen-3] = 0;
szPythonDll[nLen-2] = 0;
printf("%s\n", szPythonDll);
//hMod = LoadLibrary(szPythonDll);
//if (!hMod)
hMod = LoadLibraryEx(szPythonDll, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
}
Thanks, Timo.
This works, it checks for the first Python3?.dll whose name is more than 11 chars long:
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals ffd:WIN32_FIND_DATA
Init
SetDllFolder "\Python" ; adjust to your setup; downloaded from here
GetFiles python3*.dll
or ecx, -1
.Repeat
inc ecx
.Until Len(Files$(ecx))>11 || ecx>=9
.if Zero?
MsgBox 0, "Dll not found", "Hi", MB_OK
Exit
.endif
Dll Files$(ecx) ; python3?.dll offers twice as many functions
Declare void Py_Initialize
Declare Py_GetBuildInfo
push ecx
SetDllFolder ; no args=go back to previous folder after declaring the functions
pop ecx
Py_Initialize()
Let edi=Py_GetBuildInfo()
Inkey "Version ", edi, " loaded from ", Files$(ecx)
EndOfCode
Output: Version tags/v3.13.0a1:ad056f0, Oct 13 2023, 09:34:45 loaded from python313.dll
Quote from: TimoVJL on December 03, 2023, 08:18:40 AMWindows API function AddDllDirectory() is useful with
LoadLibraryEx(szPythonDll, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
LOAD_LIBRARY_SEARCH_USER_DIRS=400h
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS=1000h
Dll "kernelbase"
Declare void AddDllDirectory, 1
AddDllDirectory(wRec$("\Python"))
Dll "python313", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS or LOAD_LIBRARY_SEARCH_USER_DIRS
Thanks, Timo, it works, but it's quite an effort. The SetDllFolder macro is straightforward, too.
With different API function:
int nLen = GetModuleFileNameW(hMod, wszPath, 260);
while (wszPath[--nLen] != '\\');
if (nLen) wszPath[nLen+1] = 0;
SetEnvironmentVariableW(L"PATH", wszPath);
MasmBasic version 20 March 2024 comes with an improved SetAccels macro:
SetAccels F1: 0
SetAccels Ctrl F2: Hlp ; no args
SetAccels Alt F2: Hlp1(22)
SetAccels Ctrl Shift F2: Hlp2(33:var444) ; see console
SetAccels Ctrl Shift F3: Hlp3(44:Hello$) ; a MsgBox
SetAccels Ctrl F1, Ctrl Shift T
SetAccels Alt F1
SetAccels Shift F1
SetAccels a, Shift B, c, D ; lowercase a, c, d work, B needs a shift
SetAccels Ctrl O: CtrlOpen
SetAccels Ctrl VK_SPACE: MyConSpace
SetAccels Ctrl Z: NoUndo
SetAccels x: LowercaseX, Shift X: UppercaseX
F1:123 means "let F1 trigger an Event Accel"
F1:someproc means "jump to someproc" - with no, one, or two arguments.
Full code attached. Please report if anything is unexpected :cool:
Hello again
I'm trying to compile simpliest code
include C:\masm32\MasmBasic\masmbasic.inc
includelib "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\ucrt\x86\ucrt.lib"
includelib C:\masm32\MasmBasic\MasmBasic.lib
.data
.code
DllEntryPoint proc
call DLLStartup
ret
DllEntryPoint endp
DLLStartup proc
MsgBox 0, Str$(eax), "-1 is less than 99:", MB_OK
ret
DLLStartup endp
End DllEntryPoint
output:
1234.asm(30) : error A2006: undefined symbol : dw2aTable
Str$(20): Macro Called From
MsgBox(0): Macro Called From
1234.asm(30): Main Line Code
by trying I found that it's caused by Str$(eax)
If i replace it with regular string everything works fine
How can i fix this? :undecided:
Quote from: Archer-Dante on May 13, 2024, 11:12:49 PMerror A2006: undefined symbol : dw2aTable
This symbol gets normally defined by the
Init (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1009) macro. It seems you are not using Init (maybe it's not possible in a DLL, I have to check that).
You can "heal" the problem with
ExternDef dw2aTable:DWORD right after the include line.
P.S.: include C:\masm32\MasmBasic\masmbasic.inc will not assemble on a machine where Masm32 is installed on drive D:
It is better to use include \masm32\MasmBasic\masmbasic.inc instead.
Is Masmbasic open source? My AV on the corporate laptop complains. Can I download it and build it from source?
Also I see mentioned that it is a library of Macros, why not just include the source?
Hi vvanag,
No, I'm afraid it's not open source. You can find bits and pieces all over the place, mainly in the Laboratory, but the whole thing is a >48,000 lines mess that I am not going to publish ever.
About half of it is macros (and you can see them all in \Masm32\MasmBasic\MasmBasic.inc), the other half is procs. Both are so complex that I have trouble understanding them myself. For example, Str$() (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1186) alone is 457 lines long - see attachment :cool:
Re AV: a known problem for Assembly code. Heuristic scanners see "wow, not written in C or Python - very suspicious!" - and flag it as malware. There is a dedicated board for this (https://masm32.com/board/index.php?board=23.0) :cool: