The MASM Forum Archive 2004 to 2012
Welcome, Guest. Please login or register.
November 23, 2019, 02:45:17 AM

Login with username, password and session length
Search:     Advanced search
128553 Posts in 15254 Topics by 684 Members
Latest Member: mottt
* Home Help Search Login Register
+  The MASM Forum Archive 2004 to 2012
|-+  General Forums
| |-+  The Workshop
| | |-+  MasmBasic
« previous next »
Pages: 1 ... 10 11 [12] 13 14 ... 21 Print
Author Topic: MasmBasic  (Read 143434 times)
jj2007
Member
*****
Gender: Male
Posts: 6011



MasmBasic: Dll & Declare, wCL$(), Err$()
« Reply #165 on: November 23, 2010, 11:03:29 PM »

New version attached at the end of the first post (some lines above Dave's post).

What's new?

Quote
include \masm32\MasmBasic\MasmBasic.inc      ; include this library
      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$(1)      ; there is no retval, so we have to test for errors
      Exit      ; do a clean exit, inter alia FreeLibrary
end start

Dll "name" loads a dll with LoadLibrary
Declare dllfunction, #args defines a macro that can be used e.g. as mov eax, MyFunc(1, eax, 3)
Housekeeping (FreeLibrary) is done with the Exit statement
The example above needs a Unicode filename, therefore wCL$().
See reply 155 for the PopCount and Rand() functions.
Logged

Antariy
Member
*****
Gender: Male
Posts: 1041


Re: MasmBasic: Dll & Declare, wCL$(), Err$()
« Reply #166 on: November 23, 2010, 11:46:30 PM »

Jochen, for Dll macro, I guess, you can return index of the DLL in EDX, in addition to EAX's handle.
Logged
jj2007
Member
*****
Gender: Male
Posts: 6011



Re: MasmBasic: Dll & Declare, wCL$(), Err$()
« Reply #167 on: November 24, 2010, 07:22:10 AM »

Jochen, for Dll macro, I guess, you can return index of the DLL in EDX, in addition to EAX's handle.

Old:
Code:
MbDllCt = -4
Dll MACRO name
  invoke LoadLibrary, repargA(name)
  MbDllCt = MbDllCt + 4
  mov DllTable[MbDllCt], eax
ENDM

New:
Code:
MbDllCt = -4
Dll MACRO name
  invoke LoadLibrary, repargA(name)
  MbDllCt = MbDllCt + 4
  mov edx, MbDllCt  ; <-------------------- like this?
  mov DllTable[MbDllCt], eax
ENDM

Like this? But how would you use this value?
Logged

Antariy
Member
*****
Gender: Male
Posts: 1041


Re: MasmBasic: Dll & Declare, wCL$(), Err$()
« Reply #168 on: November 24, 2010, 09:52:28 PM »

Like this? But how would you use this value?

Well, this can be convenient, can be. (maybe I'll want to replace handle of dll in the table) Tongue

 BigGrin
Logged
jj2007
Member
*****
Gender: Male
Posts: 6011



MasmBasic bugfix
« Reply #169 on: November 27, 2010, 01:17:50 AM »

Bugfix: CL$() returned the commandline correctly but unfortunately did not correct the stack properly redface
Use version 27.11.2010 on top of thread. It has also a slight improvement of the Declare macro.
The snippet below g-zips the file obtained from the commandline.

Quote
include \masm32\MasmBasic\MasmBasic.inc
   Init
   Dll
"\masm32\RichMasm\zLib\zlib1.dll"  ; make sure zlib1.dll is present
   Declare gzopen, C:2
   Declare gzwrite, C:3
   Declare gzclose, C:1
   mov ebx, gzopen("TheTest.gz", "wb6")
   Let esi=FileRead$(CL$())
   mov ecx, gzwrite(ebx, esi, Len(esi))
   Inkey Str$("retval=%i, ", gzclose(ebx)), Str$("compressed=%i\n", ecx)
   Exit
end start
Logged

dedndave
Member
*****
Posts: 12523


Re: MasmBasic
« Reply #170 on: November 27, 2010, 03:02:30 AM »

oops !
glad you fixed it, Jochen

Z sends a K - no tongue  Tongue
Logged
jj2007
Member
*****
Gender: Male
Posts: 6011



Re: MasmBasic
« Reply #171 on: November 27, 2010, 07:43:09 AM »

Z sends a K - no tongue  Tongue
Hey, you are not jealous, are you?

@Alex: Set RetDllCt = 1 to get in edx the handle offset (mov DllTable[edx], eax)

Quote
RetDllCt = 0  ; default: don't return the offset
Dll
MACRO name
  invoke LoadLibrary, repargA(name)
  test eax, eax
  ExternDef MbError0:NEAR
  je MbError0
  MbDllCt = MbDllCt + 4
  if RetDllCt
   push MbDllCt
   pop edx
   mov DllTable[edx], eax
  else
   mov DllTable[MbDllCt], eax
  endif
ENDM

Declare allows now C calling convention and variable # of args:
Quote
   Declare gzwrite, C:3   ; C calling convention, three args
Quote
   Dll "msvcrt"
   Declare sprintf, C:?   ; C calling convention, variable # of args
   void sprintf(offset msgtext, "%016I64u", i64)      ; low & high dword of i64 managed by macro
   Print offset msgtext, 13, 10
   ; Masm32 syntax for static link: invoke crt_sprintf, offset msgtext, offset format, i64
void means discard the retval (which is a rather useless "# of chars written" for sprintf).
Logged

jj2007
Member
*****
Gender: Male
Posts: 6011



Re: MasmBasic
« Reply #172 on: November 30, 2010, 10:34:22 AM »

Update (attached on top of thread):

Quote
include \masm32\MasmBasic\MasmBasic.inc
   Init
   GetFiles
\masm32\m32lib\*.asm
   ZipFiles "The_Masm32_lib"
   UnZipFiles "The_Masm32_lib", "\masm32\ZipTest"
   Inkey "Archive zipped & unzipped, everything ok?"
   Exit
end start

This full-fledged Windows console application assembles fine with Masm 6.15 and higher or JWasm, and
- zips the whole \masm32\m32lib\*.asm folder
- and unzips it to \masm32\ZipTest\masm32\m32lib\*.asm
Compression is roughly 10:1, with 53,775 bytes for The_Masm32_lib (for comparison: WinZip "Maximum portable": 182,884 bytes)

For options, see MbGuide.rtf in the MasmBasic package.
Logged

jj2007
Member
*****
Gender: Male
Posts: 6011



Re: MasmBasic
« Reply #173 on: December 13, 2010, 11:50:11 PM »

Update (attached on top of thread): New AddFiles, AddFolders, SendData functions.

GetFiles has got companions, and has learnt to recurse into subdirectories:
Quote
GetFiles, AddFiles
   GetFiles filter [, startpattern] [, endpattern or lines matching] [, case sensitivity and full mode]
   GetFiles *.inc      ; fill the Files$() array with *.inc files of the current directory
   AddFiles Help\*.hlp
|*.chm   ; add to the Files$() array hlp or chm files from the Help subfolder
   mov ebx, eax      ; eax=# of files found
   Print Str$("\nFound %i files matching *.inc:", ebx)
   For_ n=0 To ebx-1
      Print CrLf$, Files$(n)
   Next

Quote
GetFolders, AddFolders
   GetFolders         ; fill the Files$() array with folders and subfolders starting with the current directory
   AddFolders \Masm32\include\*      ; add to the Files$() array folders and subfolders of the specified directory
Rem   - returns # of created lines in eax and MbGetFileCount
    - can be combined with GetFiles/AddFiles

ZipFiles
   GetFiles \masm32\m32lib\*.asm
   ZipFiles "The Masm32 lib"   ; the minimum: just the name of the *.arc archive
   
; with archive name, file count, show, Launch console mode:
   ZipFiles "The_Masm32_lib", 10, SW_MINIMIZE,
CREATE_NEW_CONSOLE   ; use first 10 files and a minimised new console
 
Rem
   - requires FreeArc in its default location (e.g. C:\Program Files\FreeArc\bin\Arc.exe)
   - creates archive in *.arc format
    - return value: see Launch
   - use MbZipLog = 1 to see the command lines in ZipLog.txt
Key   -

UnZipFiles

   
UnZipFiles "The_Masm32_lib"      ; unzip The_Masm32_lib.arc, restoring the tree on the current drive
   ; with archive name, a new destination folder, show, Launch console mode:
   UnZipFiles "The_Masm32_lib", "\masm32\ZipTest", SW_MINIMIZE, CREATE_NEW_CONSOLE   ; unzip the tree to new folder
Rem
   - requires FreeArc in its default location (e.g. C:\Program Files\FreeArc\bin\Arc.exe)
   - creates archive in *.arc format
    - return value: see Launch
   - use MbZipLog = 1 to see the command lines in ZipLog.txt

For Inter-Process Communication, the SendData/CopyData$() pair is easy to use:
Quote
CopyData$()
   SetWin$ hEdit="Just received:"+CrLf$+CopyData$()+CrLf$+"--- end of data ---"      ; use directly to set a window content
   Let My$="Just received:"+CrLf$+CopyData$()+CrLf$+"--- end of data ---"      ; store away for later use
Rem   - for receiving data from other apps; for use inside a WM_COPYDATA message handler, for example:
  SWITCH uMsg
  CASE WM_COPYDATA
      Let My$=CopyData$()+CrLf$+"received "+Time$

For sending data, use SendData

SendData
   SendData
"MyClient", Win$(hEdit)
   SendData "MyClient", "How are you?"
Rem   - returns DWORD in eax: 0=no client found
   - can also be used from a Win32 console application
Logged

jj2007
Member
*****
Gender: Male
Posts: 6011



Re: MasmBasic
« Reply #174 on: December 14, 2010, 10:00:36 PM »

With bugfixes, version 141210b is attached on top of thread. Note the syntax for Timer has changed - before it was Timer(), but I have now found a way to convince MASM 6.15, 9.0 and JWasm to accept that there are no brackets. In general, I try to avoid useless trailing brackets; there are a few exceptions, such as
Code:
Let My$=Clip$()    ; get all available text from clipboard
Let My$=Clip$(100) ; get up to 100 bytes

Let My$=CL$(0)     ; get arg #0, i.e. the current executable
Let My$=CL$()      ; get first arg of the commandline (i.e. #1 is the default arg)
Let My$=CL$(2)     ; get second arg of the commandline

The Server/Client example for IPC with SendData/CopyData$ has been improved, too.

Alex (Antariy) asked me if GetFiles checks for maximum recursion depth. Actually, it doesn't, and tests seem to prove that it doesn't matter. There is an old thread discussing this:

The stack reserves the size specified by the linker but it doesn't commit it until you try and access it. It detects attempted accesses using a guard page, so the first time you attempt to access a page that hasn't been committed, Windows will catch an exception and commit it. However, it only guards one page, which is the next uncommitted page. Attempting to access the page beyond the guard page will cause an access violation exception.

The critical sentence here is "Attempting to access the page beyond the guard page will cause an access violation exception". A recursive FindFirstFile proc allocates a few hundred bytes per recursion, and thus will never throw an exception. Attached is a zip archives that extracts two zero byte files to a 48 levels deep folder ("use folder names" option in WinZip required). Test it with this snippet:

Code:
include \masm32\MasmBasic\MasmBasic.inc ; http://www.masm32.com/board/index.php?topic=12460
Init
GetFiles \masm32\RichMasm\*.rt ; recurse until you find files with extension *.rt
push eax
For_ n=0 To eax-1
PrintLine Str$("#%i\t", n), Files$(n)
Next
pop eax
Inkey Str$("\n%i files found", eax)
Exit
end start

The test also reveiled that WinXP stops at a total names length of 256 bytes, i.e. even when using single letter folder names, the theroretical maximum recursion level is apparently 256.

* Rt45.zip (1.12 KB - downloaded 173 times.)
Logged

dedndave
Member
*****
Posts: 12523


Re: MasmBasic
« Reply #175 on: December 14, 2010, 10:11:18 PM »

Jochen,
i know, with XP, you can't go as deep with
CD c:\a\a\a\a...\a\a\a
as you can with
CD c:\a
CD a
CD a
CD a
...
CD a
CD a
CD a

the point being, it matters if it is root-relative or current-relative
Logged
jj2007
Member
*****
Gender: Male
Posts: 6011



Re: MasmBasic
« Reply #176 on: December 14, 2010, 10:34:19 PM »

Unzip the archive to C:\, then go to the last level and try an mkdir dedndave...

Re Client/Server example: If you want some fun, try (in \masm32\RichMasm\Res\Server.asc):
Code:
case IdEdit
  push esi
  Let esi=Win$(hEdit)+CrLf$+FileRead$("\Masm32\include\Windows.inc")+FileRead$("\Masm32\include\WinExtra.inc")
  SendData "MyClient", esi, hWnd
  Clr$ esi
  pop esi

Type something while MyClient is active... it feels like Microsoft Word green
Logged

Antariy
Member
*****
Gender: Male
Posts: 1041


Re: MasmBasic
« Reply #177 on: December 15, 2010, 01:09:01 AM »

Alex (Antariy) asked me if GetFiles checks for maximum recursion depth. Actually, it doesn't, and tests seem to prove that it doesn't matter. There is an old thread discussing this:

The stack reserves the size specified by the linker but it doesn't commit it until you try and access it. It detects attempted accesses using a guard page, so the first time you attempt to access a page that hasn't been committed, Windows will catch an exception and commit it. However, it only guards one page, which is the next uncommitted page. Attempting to access the page beyond the guard page will cause an access violation exception.

The critical sentence here is "Attempting to access the page beyond the guard page will cause an access violation exception".

My point was not trying to access beyond guard page, untill you did'n allocate more than 4 KB this would not occur. With using of your macro for clearing local variables, this will not occur even with over 4 KB buffers.
My point is: you just can reach end of all space allocated for stack, if recursive function take too many data as local variables. At least, WFD structure have size over 300 bytes, and for each level of recursion this will increase linearly. If proc have other fat local data, then you just *can* reach end of the stack, with funny exception (and probably without any Windows "Error reporting" message) lol
Logged
dedndave
Member
*****
Posts: 12523


Re: MasmBasic
« Reply #178 on: December 15, 2010, 01:32:06 AM »

the stack has a lot of room to work in win 32   BigGrin
Logged
Antariy
Member
*****
Gender: Male
Posts: 1041


Re: MasmBasic
« Reply #179 on: December 15, 2010, 02:20:19 AM »

the stack has a lot of room to work in win 32   BigGrin

Dave, this discussion is not interesting. I dislike to to rend the air with such conversations.
BUT, for example, imagine that your recursive function have 600 (only 600!!!) bytes of local variables. And >300 from them - the WFD structure only.
So, for 128 levels (for example) of recursion, you will grab 128*600=75 KB of the stack space. At point of 1 meg default linking stack space, this is not so small. You shouldn't decise that "almost all stack is mine". In some relatively deep call you will get a stack overflow, and exit without any "error message", since SEH cannot work in this case.
Of course, you "will get a stack overflow" only for 50/50, dependedly from case and application. But this lottery should not pleasing you.

Tongue

P.S. TotalCommander in near back have funny stack overflows by many cases, if you don't trust me Tongue
Logged
Pages: 1 ... 10 11 [12] 13 14 ... 21 Print 
« previous next »
Jump to:  

Powered by MySQL Powered by PHP The MASM Forum Archive 2004 to 2012 | Powered by SMF 1.0.12.
© 2001-2005, Lewis Media. All Rights Reserved.
Valid XHTML 1.0! Valid CSS!