Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu


Started by mabdelouahab, December 01, 2017, 07:47:15 PM

Previous topic - Next topic


AsmDotNet64 Is a new version of masm32Ref, works on X64 platform, to deal with .net framwork, for Masm64 and Uasm64, We can use it with MasmBasic, we designed it to work in an easy way.

how to use AsmDotNet64?


         include;   Necessary, (The AsmDotNet64 include file./With:Masm64Ref.Lib)

   .import Dot_Net_Assembly,Assembly_Alias
      Dot_Net_Assembly         : the fully qualified name of the type that we want to work on, ex: System.Windows.Forms.Form
      Assembly_Alias   (Optional)   : The alias that we will need to shorten the assembly name

      .import System.Windows.Forms.Form ,Forms
      .import System.Windows.Forms.MessageBox ,MsgBox


      - ".import Dot_Net_Assembly" This macro inserts (include) a file named file
      if this file is not en the same directory, we must adjust the correct directory by using: " ClrDirectory equ <DIRECTORY> "

         ClrDirectory equ <\Masm32\Include\CLR\>
         ClrDirectory equ <.\CLR\>

      - To get an Inc file of .net assembly use Masm64Ref.exe

Declaration :

- Global variable: must be in .data section
   .global New_Variable_Name,Dot_Net_Assembly
- Local variable:
   .local New_Variable_Name,Dot_Net_Assembly

      New_Variable_Name         : Name of the Variable
      Dot_Net_Assembly          : Name of the type (or Assembly_Alias) that we want to work on.


         .global Frm01,System.Windows.Forms.Form
         .global Msg1,System.Windows.Forms.MessageBox
         .global Msg2,MsgBox
         MyProc PROC
            LOCAL L1,L2
            .LOCAL Msg__Box,MsgBox
            LOCAL L3

Create new instance:
   If we declare variable Var, to create new instance we must invoke "CreateInstance" method using:
      .invoke Var.CreateInstance
   With/Without parameter, depending on what the type contains (Constructor)
   If this type contains several constructor, The "CreateInstance" would add to it a underscore with a number; CreateInstance,CreateInstance_1,CreateInstance_2,...

         .import System.Windows.Forms.Form ,Forms
         .global Frm,Forms
         entry_point proc
            .invoke Frm.CreateInstance   

Invoke method:
   we can invoke any method of an declared variable using ".invoke" macro:
   .invoke Var.Method,Parameters
   If this type contains several Method withe defirent parameters type, The name of Method would add to it a underscore with a number; Method,Method_1,Method_2,...
   There is a difference between this version and the previous version, we can now use the masm type without having to pass it as a VARIANT
   Provided that it is:
      System.Boolean   :Word   
      System.DateTime :Qword
      System.Double    :IEEE 64-bit floating-point number (REAL8)
      System.Single    :IEEE 32-bit floating-point number (REAL4)
      System.UInt64    :Unsigned 64-bit integer
      System.Int64    :Signed 64-bit integer
      System.UInt32    :Unsigned 32-bit integer
      System.Int32    :signed 32-bit integer
      System.UInt16    :Unsigned 16-bit integer
      System.Int16    :signed 16-bit integer
      System.Byte    :Unsigned 8-bit integer
      System.SByte    :signed 8-bit integer
      System.Array    :pointer to SAFEARRAY
      System.Char    :pointer to wchar
      System.String    :pointer to BSTR
      System.IntPtr    :Signed native integer; equivalent to the machine word size (32 bits on a 32-bit machine, 64 bits on a 64-bit machine)
      System.UIntPtr    :UnSigned native integer;   
      System.Runtime.InteropServices.ErrorWrapper    :DWORD
      System.Runtime.InteropServices.CurrencyWrapper    :QWORD


         .import System.Windows.Forms.MessageBox,tMessageBox

         .import System.Windows.Forms.MessageBoxButtons
         .import System.Windows.Forms.MessageBoxIcon
         .import System.Windows.Forms.MessageBoxDefaultButton
         .import System.Windows.Forms.MessageBoxOptions
         .import System.Windows.Forms.DialogResult
         .global Msg__Box,tMessageBox
         entry_point proc
            .invoke Msg__Box.Show,   "Text string",\
                              "Caption string",\
                              addr pRetVal
            .if RAX==DialogResult_Yes
               .invoke Msg__Box.Show_14,   " you are choise Yes",0

Get/Set Property/Field:
   we can affecte a value to any property of an declared variable using ".set" macro, or get value of any property using ".get" macro:
   .set Var.propertyName,NewValue
   .get desitination , Var.propertyName
      propertyName            : Name of the Property
      NewValue               : Value ; The same thing as it is in Method Parameters
      desitination            : Pointer to Variant, or if the return value the same type as it is in Method Parameters the
                              value return in rax and leave the desitination blank

         txt   dq   0
            .invoke vForm.CreateInstance      
            .set vForm.Text,"Masm64Ref Example"
            .set vForm.Width,1000
            .set vForm.Height,500
            .get ,vForm.Text
            mov txt,RAX
            .invoke vForm.ShowDialog

Add/Remove an Event Handler:            
   we can Add an Event Handler of an declared object using ".AddHandler" macro, or remove it using ".RemoveHandler" macro:
   .addhandler Var.EventName,lpFunction,handler
   .removehandler  Var.EventName,handler

      propertyName            : Name of the Event
      lpFunction               : Pointer to CallBack Function
      handler                  : Pointer to Variant, to get handler (Delegate),We can use it to removehandler ;or leave it empty


         .import System.Windows.Forms.Form ,tForm
         .global    vForm,tForm
         txt         dq   0
         hand__      VARIANT   <>
         On_Closed   PROC _sender:xWORD, _e:xWORD
         On_Closed   ENDP
         entry_point proc
            .invoke       vForm.CreateInstance      
            .AddHandler    vForm.Closed,addr On_Closed,addr hand__
            ;.RemoveHandler vForm.Closed,addr hand__
            .invoke       vForm.ShowDialog


Hello World:
   ;include \masm32\include64\    ; For MASM64
   ;include \Masm32\MasmBasic\Res\   ; For MasmBasic

   include \masm32\include64\AsmDotNet64.Inc
   ; UAsm
   .includelib kernel32,user32,msvcrt, oleaut32, ole32
   .proto wprintf,printf,ExitProcess
   ;ClrDirectory equ <C:\....\>; dotnet assembly includes path
   .import System.Windows.Forms.Form,tForm
   .import System.Windows.Forms.MessageBox,tMessageBox

   .global vForm   ,tForm
   .global Msg__Box,tMessageBox

   On_Closed proc _Sender:QWORD,_e:QWORD
      .LOCAL LMsg__Box,tMessageBox
      .invoke LMsg__Box.Show_14," you are in testt proc"

   On_Closed endp

   ;Init      ; OPT_64 1
   entry_point proc
      LOCAL hand__:VARIANT
      ;.initCLR   ;Optional: .initCLR,.initCLR2,.initCLR4
      .invoke vForm.CreateInstance
      .set vForm.Text,"AsmDotNet64: Hello World"
      .set vForm.Width,1000
      .set vForm.Height,500
      .addhandler vForm.Closed,addr On_Closed
      .invoke vForm.ShowDialog
       invoke ExitProcess,0
   entry_point endp


Quote from: mabdelouahab on December 01, 2017, 07:47:15 PMWe can use it with MasmBasic

Hi mabdelouahab,
I first thought you were joking, but it assembles indeed with some minor tweaking :t

But I get runtime errors for the hello world example:
  Fail to set Property, HRESULTS=[80070057]
  Fail to set Property, HRESULTS=[80070057]
  Invoke Method Fail, HRESULTS=[8002000E]

Maybe it would be helpful if you could explain the setup, i.e. which files have to be where, relative to the \Masm32 root.


Hello Joshen
Such errors occur when the CLR is loaded in a specific version, and a reference Assembly is loaded for a different version
In the previously inserted example, the reference assembly is to the version 4 ( For CLR 4: .net Framwork 4,4.5,...), if this vertion is not installed in you system , the less version will be loaded automatic , and you get such errors
To avoid this, you must select the vertion that you want to work on directly, by :

.initCLR2 ;For Clr 2 (.net V2,V3,V3.5)
.initCLR4 ;For Clr 4 (.net V4,V4.5,V4.6 ...)


To determine which reference you want to work on, use the tool  Masm64Ref.exe
In the previous example, we want to work on Form Assembly (System.Windows.Forms.Form)
After you open the tool , search for: "System.Windows.Forms.Form,...." from list, then you choose which version you want to work on.

Then select the folder where you want to place the reference


Quote from: mabdelouahab on December 03, 2017, 10:14:52 PM
Hello Jochen

..\MasmBasic\HWAsmDotNet64.asc builds "out of the box" and works perfectly, nice :t


new update, the new version included:
   - get/set static propertry
   - ".addhandlerEx"  for the event that give rise to the exception 0x80131509 :
            "This type has a ComVisible(false) parent in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed."
   - ".wpf_xamlcontent": Specially for WPF, To set the window.content" property a reference to an xaml source string
        syntax: .wpf_xamlcontent Window,addr cstrSourceString
              window: instanse of an object of type System.Windows.Window
              cstrSourceString: ansi string; Extensible Application Markup Language (XAML)
              Return Value: qword value, instanse of an object of type System.Windows.Markup.XamlReader

   - ".wpf_FindLogicalNode " : LogicalTreeHelper.FindLogicalNode
        syntax: .wpf_FindLogicalNode XamlReader, elementName, RetValue
              XamlReader:instanse of an object of type System.Windows.Markup.XamlReader
              elementName: The name of the object to find.
              return value :The object with the matching name (Type: System.Windows.DependencyObject)             


include \masm32\include64\
includelib kernel32.lib
ExitProcess proto :dword

.import System.Windows.Window,tWindow
.import System.Windows.Controls.Border,tBorder
.import System.Windows.Media.Brushes,tBrushes
.global vWindow,tWindow
.global vBrushes,tBrushes
.global vBorder,tBorder

SourceString db '<StackPanel' ,13,10
        db ' xmlns=""',13,10
        db ' xmlns:x="" ' ,13,10
        db ' Orientation="Vertical">' ,13,10
        db '<Border Name="B11" BorderBrush="White" CornerRadius="6" BorderThickness="1"' ,13,10
        db ' Background="#B4D74A2C" Width = "640" Height = "480">' ,13,10
        db '   <TextBlock Name="TT1"  HorizontalAlignment="Center" VerticalAlignment="Center"' ,13,10
        db '    FontSize="34">AsmDotNet64</TextBlock>' ,13,10
        db '</Border>' ,13,10
        db '</StackPanel>' ,0


On_MouseRightButtonDown proc _Sender:QWORD,_e:QWORD
.invoke vWindow.Close
On_MouseRightButtonDown endp

entry_point proc
LOCAL LvXamlReader:Qword
LOCAL LvtTransparent:VARIANT

.invoke vWindow.CreateInstance

.get addr LvtTransparent,vBrushes.Transparent
.set vWindow.Background,addr LvtTransparent
.set vWindow.AllowsTransparency,-1 ;TRUE
.set vWindow.WindowStyle,addr LvtWindowStyle

.wpf_xamlcontent vWindow,addr SourceString
mov LvXamlReader,rax
.wpf_FindLogicalNode LvXamlReader, "B11", vBorder

.addhandlerEx vBorder.MouseRightButtonDown,addr On_MouseRightButtonDown

.invoke vWindow.ShowDialog ,0
invoke ExitProcess,0

entry_point endp


Hi mabdelouahab,

downloading from sourceforge always breaks, it would be cool to have a mirror on Github. Thanks for the update  :t


Hi LiaoMi
The files do not exceed 375 KB,I put them here at the beginning of this topic, I think this is better , Thanks  :t