News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Miscellaneous snippets

Started by jj2007, August 20, 2017, 08:02:31 AM

Previous topic - Next topic

jj2007

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals REAL8 min8, max8
  Init
  PrintCpu 0
  elements=2000000              ; two Million elements
  Dim MyReal8() As REAL8
  For_ ct=0 To 19
        .if !Exist("MyReals.dat") || ct<5       ; measure creation times for the first 5
                NanoTimer()
                For_ ecx=0 To elements-1
                    Rand(-100, 100, MyReal8(ecx))   ; create a random number between -100 and +100
                Next
                PrintLine Str$("Creating an array of %i random doubles took ", ecx), NanoTimer$()
                ArrayStore "MyReals.dat", MyReal8()
        .endif
        NanoTimer()
        ArrayRead MyReal8(), "MyReals.dat"      ; read array from disk
        ArrayMinMax MyReal8(), min8, max8       ; assign min+max to two variables
        PrintLine Str$("Reading and getting min=%7f", min8), Str$(" and max=%7f took ", max8), NanoTimer$()
  Next
  Inkey "hit any key"
EndOfCode


Output:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
Creating an array of 2000000 random doubles took 83 ms
Reading and getting min=-99.99998 and max=99.99964 took 29 ms
Creating an array of 2000000 random doubles took 37 ms
Reading and getting min=-99.99989 and max=100.00000 took 43 ms
Creating an array of 2000000 random doubles took 39 ms
Reading and getting min=-99.99983 and max=99.99999 took 31 ms
Creating an array of 2000000 random doubles took 38 ms
Reading and getting min=-99.99996 and max=99.99998 took 32 ms
Creating an array of 2000000 random doubles took 38 ms
Reading and getting min=-99.99998 and max=99.99991 took 28 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 26 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 26 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 28 ms
Reading and getting min=-99.99998 and max=99.99991 took 25 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 31 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms
Reading and getting min=-99.99998 and max=99.99991 took 28 ms
Reading and getting min=-99.99998 and max=99.99991 took 30 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms


See also GB32 forum

jj2007


HSE

Hi JJ!

Where are your benmarchs of GB32?
Equations in Assembly: SmplMath

jj2007

Embedded in the source. The code is based on scalion's alias Nicolas Rey's tests.

QuoteThe program consist in 4 test :

Test 1 "Init" - Initialisation of 10000 item of string array with a letter followed by numbers.
Test 2 "Swap" - Swap all items one time with another (not sorting) ->  49 995 000 swaps.
Test 3 "Mid" - Concat each 9999 first items with 2 parts of item+1 : mid(a(i+1),2) + mid(a(i+1),1,1)
Test 4 "Sort" - Sort ascending the array.

HSE

Equations in Assembly: SmplMath

jj2007

include \masm32\MasmBasic\MasmBasic.inc         ; download
  SetGlobals buffer[40]:BYTE
  Init
  lea edi, buffer
  invoke GetLogicalDriveStrings, 40, edi
  ; Print HexDump$(edi, 32)
  lea esi, [edi-2]             ; to compensate leading 2*inc
  .While 1
        inc esi
        inc esi
        m2m edx, 32             ; len of buffer
        .Break .if !Instr_(FAST, esi, ":\", 2 or 64)    ; 64=len in edx, 2=ignore case of first char
        lea esi, [eax-1]        ; put esi on the drive letter
        xchg rv(GetDriveType, esi), ecx
        .if Choose(ecx, "unknown", "no root", "removable", "fixed", "remote", "cdrom", "ramdisk")==ChooseString         ; *)
                PrintLine esi, " is type ", eax         ; Str$(" (value %i)", ecx)
       .else
                PrintLine "Drive ", esi, Str$(" is type %i", ecx)
        .endif
  .Endw
EndOfCode

*):
unknown         equ 0
no root         equ 1
DRIVE_REMOVABLE equ 2
DRIVE_FIXED     equ 3
DRIVE_REMOTE    equ 4
DRIVE_CDROM     equ 5
DRIVE_RAMDISK   equ 6


C:\ is type fixed
D:\ is type cdrom
E:\ is type removable
J:\ is type fixed

jj2007

Just for fun :biggrin:

include \masm32\MasmBasic\MasmBasic.inc         ; download
  Init
  MbHexDumpLen=819200           ; let's be generous (default is 8192 bytes)
  Let esi=FileRead$(CL$())      ; read the file supplied in the commandline
  FileWrite "~testTmp.asm", HexDump$(esi, LastFileSize, dq)     ; use QWORD format
  ShEx "~testTmp.asm"           ; open in your IDE
EndOfCode


Usage: drag any executable (any file, actually) over bin2dq.exe

Output:
.DATA
hdBytes=49152
hdStart LABEL BYTE
.radix 16
dq 00000000300905A4D, 00000FFFF00000004, 000000000000000B8, 00000000000000040, 00000000000000000, 00000000000000000, 00000000000000000, 00000008000000000
dq 0CD09B4000EBA1F0E, 0685421CD4C01B821, 072676F7270207369, 06F6E6E6163206D61, 06E75722065622074, 020534F44206E6920, 00A0D0D2E65646F6D, 00000000000000024
...
dq 00D3E796C626D6573, 0000000000000000A, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
dq 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
dq 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
.radix 10
.code
; FileWrite "test.exe", offset hdStart, hdBytes


P.S., to test your result, you can use, for example:

include \masm32\MasmBasic\MasmBasic.inc
include ~testTmp.asm

  Init
  FileWrite "bin2test.exe", offset hdStart, hdBytes
  Launch "bin2test.exe"
EndOfCode


If you prefer pure Masm32 SDK for testing, use this:

include \masm32\include\masm32rt.inc
include ~testTmp.asm

.code
start:
  invoke write_disk_file, chr$("bin2test.exe"), offset hdStart, hdBytes  ; re-create the exe
  invoke WinExec, chr$("bin2test.exe"), SW_SHOW
  exit
end start

jj2007

Attached a program I am just working on, with several different kinds of buttons.

What is interesting: It behaves differently on Win 7 and Win 10. On the latter OS, some of the buttons receive up to 8 WM_PAINT messages in a row. Something is seriously wrong, and I am trying to find out what. It might have to do with a different behaviour of the CDDS_* messages, but I am not yet sure. I will keep you posted.

quarantined

Quote from: jj2007 on August 15, 2022, 06:22:16 AM
Something is seriously wrong, and I am trying to find out what....

Thanks, but what I posted in the Campus is not supposed to act like a button exactly. It behaves like I intended it to.  :cool:

NoCforMe

Well, that's OK. There's no law that says you can't make a static control behave enough like a button to suit your purposes. You won't get a knock on your door in the middle of the night from the Coding Police.
Assembly language programming should be fun. That's why I do it.

jj2007

#190
Just for fun - project attached. TinyCalcV2.zip is an advanced version with hex and binary display. It will accept most common number formats as input.

GuiParas equ "Tiny calculator", w200, h130, m4, b LiteBlueGreen ; width+height, margins, background colour
include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl Calc, "Edit", bcol LiteYellow, w700, fcol Black, font -14, h0+32 ; colours & fonts have no effect with rtf files
  GuiControl Go, "button", "-!!> clipboard", x700, w300, h0+32, bcol LiteYellow
  GuiControl Status, "statusbar", "Type a formula"
  SetGlobals Result:REAL10, res$
Event Command
  .if MenuID==Go && nCode==BN_CLICKED
SetClip$=res$
invoke SendMessage, hWnd_, WM_CLOSE, 0, 0
  .elseif MenuID==Calc && nCode==EN_CHANGE
xor ecx, ecx
SetWin$ hStatus=0
mov esi, Win$(hCalc)
.if Instr_(esi, "+")
inc ecx
.else
.if Instr_(esi, "-")
inc ecx
inc ecx
.else
.if Instr_(esi, "*")
dec ecx
.else
.if Instr_(esi, "/")
dec ecx
dec ecx
.endif
.endif
.endif
.endif
.if ecx
mov byte ptr [eax], 0 ; separate left and right halves
inc eax
MovVal ST(0), eax ; right half of expression
.if edx && edx<20
MovVal ST(0), esi
Switch_ ecx
Case_ 1: fadd
Case_ 2: fsubr
Case_ -1: fmul
Case_ -2: fdivr
Endsw_
fstp Result
Let res$=Str$(Result)
xchg eax, ecx
push ecx
add ecx, Len(ecx)
.Repeat
dec ecx
.Until byte ptr [ecx]!="0"
mov byte ptr [ecx+2], 0
pop eax
SetWin$ hStatus=Cat$("Result="+res$)
.endif
.endif
  .endif
GuiEnd

jj2007

This grew quickly, the source is now a whopping 149 lines :biggrin:

Version 3 has a tooltip, knows about 2**3=8 and accepts PI as first parameter. Enjoy :biggrin:



P.S.: Binary result and bit descriptor for e.g. 123*456 look like this:

1101101100011000
5432109876543210

It can be helpful to see which bits are set.

jj2007

Kuron posted a coded message, here is how to decipher the text:
include \masm32\MasmBasic\MasmBasic.inc
  Init
  Let esi=Replace$("01010010 01001001 01010000 00100000 01001000 01110101 01110100 01100011 01101000 00101110 00100000 01011001 01101111 01110101 00100000 01110111 01101001 01101100 01101100 00100000 01000010 01100101 00100000 01001101 01101001 01110011 01110011 01100101 01100100 00100001 ", " ", Chr$("b", 13, 10))
  Let edi=""
  .While 1
    .Break .if Val(esi)==-127    ; -127 flags "invalid string"
    and edx, 15    ; isolate #characters used
    add esi, edx
    Let edi=edi+Chr$(eax)
  .Endw
  MsgBox 0, edi, "A message from Kuron:", MB_OK
EndOfCode

Let esi=Replace$("01010010 ... 00100001 ", " ", Chr$("b", 13, 10)) translates the string in esi to a valid format suitable for Val():
01010010b
01001001b
01010000b
00100000b
01001000b
01110101b
01110100b
01100011b
01101000b
00101110b
00100000b
01011001b
01101111b
01110101b
00100000b
01110111b
01101001b
01101100b
01101100b
00100000b
01000010b
01100101b
00100000b
01001101b
01101001b
01110011b
01110011b
01100101b
01100100b
00100001b

jj2007

Here is an example of a badly documented MasmBasic function:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  DlgDefine "Ida is cute", 0, 0, 60, 62
  DlgControl dcStatic, "Ida.ico", SS_ICON, 0, 0
  DlgShow
EndOfCode

Project attached - extract all files to a folder, then run the exe (or build it with RichMasm).

Caché GB

Hi JJ

I am always willing to learn. As I have told you a few times, I have learnt to much from you.
However it would be quicker for me to drop your .exe into IDA to try and find out what is giong
on then to waddle through a billion lines of MasmBasic's macros.

So maybe a pure MASM demo would be nice.

Thanks.
Caché GB's 1 and 0-nly language:MASM