News:

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

Main Menu

Assembly uses Python

Started by jj2007, November 30, 2023, 01:49:37 AM

Previous topic - Next topic

jj2007

Just for fun

include \masm32\MasmBasic\MasmBasic.inc
include SetDllFolder.mac        ; will be included in the next edition of MasmBasic
  Init
  SetDllFolder "\Python"        ; adjust to your setup; downloaded from here (direct link)
  Dll "python3.dll"        ; python38.dll has >1600 functions; use Windows embeddable package (32-bit) here
  Declare PyList_New, C:1
  Declare void Py_Initialize
  Declare void Py_FatalError, C:1
  Declare void PySys_WriteStdout, C:?    ; ?=vararg
  Declare PyList_New, C:1
  Declare PyList_Size, C:1        ; PyList_Size(PyObject *list)
  Declare PyList_SetItem, C:3    ; PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
  Declare PyList_GetItem, C:2    ; PyList_GetItem(PyObject *list, Py_ssize_t index)
  Declare PyList_Sort, C:1        ; PyList_Sort(PyObject *list); reverse flag
  Declare PyList_Reverse, C:1    ; PyList_SortReverse(PyObject *list)
  SetDllFolder
  Py_Initialize()
  Recall "\Masm32\include\Windows.inc", L$()    ; load a string array
  mov edi, PyList_New(eax)
  For_ ct=0 To L$(?)-1
    void PyList_SetItem(edi, ct, L$(ct))
  Next
  Print Str$("%i elements copied\n", PyList_Size(edi))
  ; crashes: void PyList_Sort(edi)
  Print Str$("Reversing returns %i\n", PyList_Reverse(edi))        ; string array topside down
  For_ ecx=PyList_Size(edi)-1 To 0 Step -1
    PrintLine Str$("%__i ", ecx), PyList_GetItem(edi, ecx)
    ; similar: PySys_WriteStdout(cfm$("%i\t%s\n"), ecx, PyList_GetItem(edi, ecx))        ; CRT printf under the hood...
  Next
  MsgBox 0, "Masm uses Python", "Hi", MB_OK

EndOfCode

Output:
26902 elements copied
26901 ;;;; head
26900
26899 comment * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
26898
26897      WINDOWS.INC for 32 bit MASM (Version 1.6 RELEASE January 2012)
26896
26895      This version is compatible with ML.EXE Version 8.0 and later.
...
  4 ELSE
  3 echo ------------------------------------------
  2 echo WARNING Duplicate include file windows.inc
  1 echo ------------------------------------------
  0 ENDIF

The need for SetDllFolder is discussed here. I have no idea why the sort crashes; from an assembly pov, this is lousily documented.

jj2007

See Getting a return value from the Python interpreter for a different way to use Python from Assembly (), using PyRun_SimpleString().

There is a third variant using PyObject_CallMethod:

  mov ioMod, PyImport_ImportModule("io")
  mov openedFile, PyObject_CallMethod(ioMod, "open", "ss", "foo.txt", "wb")
  Py_DecRef(ioMod)
  void PyObject_CallMethod(openedFile, "write", "y", "Written from Python C API!\n")
  void PyObject_CallMethod(openedFile, "flush", NULL)
  void PyObject_CallMethod(openedFile, "close", NULL)
  Py_DecRef(openedFile)

I also sorted out the PyList_Sort() problem (it crashed). You can't assign string pointers directly via SetItem, they must first be converted to "bytes from string", whatever that means:
  For_ ct=0 To L$(?)-1
    void PyList_SetItem(edi, ct, PyBytes_FromString(L$(ct)))
  Next

Building the source requires MasmBasic 2 December 2023.