This file syswin.htm
is MS Windows version of macroinstructions which encapsulate system calls in EuroAssembler.
List of services hired from Windows API:
CloseHandle
CreateDirectory
CreateFile
CreateFileMapping
ExitProcess
FileTimeToDosDateTime
FindClose
FindFirstFile
FindNextFile
GetCommandLine
GetEnvironmentVariable
GetLastError
GetModuleFileName
GetModuleFileName
GetModuleHandle
GetSystemInfo
GetSystemTime
GlobalFree
MapViewOfFile
MultiByteToWideChar
SetFilePointer
SystemTimeToFileTime
UnmapViewOfFile
VirtualAlloc
VirtualFree
WriteFile
In order to port EuroAssembler to a different operating system:
- Specify 1..4 character shortcut of the system, e.g.
Lin, BSD, OS2, Sol,...and set it to %^EuroasmOS variable instead ofWin.- Create source file
sys%^EuroasmOS.htm, similar to thissyswin.htm.- Rewrite all macros in this source file, exactly keeping their parameters, input, output and functionality.
- Rebuild EuroAssembler.
- Update documentation.
syswin PROGRAM FORMAT=COFF,MODEL=FLAT,WIDTH=32
INCLUDEHEAD "euroasm.htm" ; Interface (structures, symbols and macros) of other modules.
syswin HEAD ; Start of interface, which is included to other modules.
INCLUDEHEAD1 winapi.htm, wins.htm, winscon.htm, winstime.htm, winsfile.htm, winfile.htm
SysGetAllocationGranularity %MACRO
PUSH EBX,ECX,EDX
SUB ESP,SIZE# SYSTEM_INFO
MOV EBX,ESP
WinAPI GetSystemInfo,EBX
MOV EAX,[EBX+SYSTEM_INFO.AllocationGranularity]
ADD ESP,SIZE# SYSTEM_INFO
POP EDX,ECX,EBX
%ENDMACRO SysGetAllocationGranularity
SysAlloc %MACRO BlockSize
PUSH ECX,EDX
MOV EAX,[Ea.MemAllocated]
MOV ECX,[Ea.MemPeak]
MOV EDX,%BlockSize
ADD EAX,EDX
MOV [Ea.MemAllocated],EAX
CMP EAX,ECX
JBE SysAlloc%.:
MOV [Ea.MemPeak],EAX
SysAlloc%.: WinAPI VirtualAlloc, 0, EDX, MEM_COMMIT, PAGE_READWRITE
TEST EAX
POP EDX,ECX
%ENDMACRO SysAlloc
SysFree %MACRO BlockAddress, BlockSize
PUSH ECX,EDX
SUB [Ea.MemAllocated],%BlockSize
WinAPI VirtualFree, %BlockAddress, 0, MEM_RELEASE
TEST EAX
POP EDX,ECX
%ENDMACRO SysFree
SysANSI2Wide %MACRO Codepage, ANSIPtr, ANSISize, WidePtr, WideSize
PUSH EAX,ECX,EDX
WinAPI MultiByteToWideChar, %Codepage, MB_PRECOMPOSED, %ANSIPtr, %ANSISize, %WidePtr, %WideSize
TEST EAX
POP EDX,ECX,EAX
%ENDMACRO SysANSI2Wide
SysAssignFile %MACRO File, FilenamePtr, FilenameSize
FileAssign %File, %FilenamePtr,Size=%FilenameSize, Unicode=0
%ENDMACRO SysAssignFile
SysCloseFile %MACRO File
FileClose %File
%ENDMACRO SysCloseFile
SysCreateFile %MACRO File, FileName$
FileAssign %File,%FileName$
FileCreate %File
%ENDMACRO SysCreateFile
SysEachFile %MACRO File, Callback
FileEach %File, %Callback
%ENDMACRO SysEachFile
SysExitProcess %MACRO Errorlevel
WinAPI ExitProcess, %Errorlevel ; WinAPI function.
%ENDMACRO SysExitProcess
2004/08/28 21:07:42 UTC represented in memory as FileTime
0x01C4_8D3A__ACCD_B800 returns DosDateTime EAX=0xF5A8_1C31.
SysFileTimeToDosDateTime %MACRO FileTimePtr
PUSH ECX,EDX,EAX
MOV EDX,%FileTimePtr
MOV EAX,ESP
LEA ECX,[EAX+2]
WinAPI FileTimeToDosDateTime, EDX,ECX,EAX
POP EAX,EDX,ECX
%ENDMACRO SysFileTimeToDosDateTime
SysGetArg %MACRO ArgNr
GetArg %ArgNr
%ENDMACRO SysGetArg
SysGetCurrentDirectory %MACRO DirNamePtr
PUSH EAX,ECX,EDX
WinAPI GetCurrentDirectoryA, MAX_PATH_SIZE, %DirNamePtr
CMP EAX,1 ; Set CF if EAX=0 on return.
POP EDX,ECX,EAX
%ENDMACRO SysGetCurrentDirectory
SysGetEnvironment %MACRO NamePtr, NameSize, OutEnvBuffer
PUSHD %OutEnvBuffer, %NameSize,%NamePtr
CALL SysGetEnvironment@RT:
SysGetEnvironment@RT: PROC1
PUSHAD
: Invoke EaBufferReserve::,SysGetEnvironment@RT
MOV EBX,EAX
MOV ESI,[ESP+36] ; NamePtr
MOV ECX,[ESP+40] ; NameSize
BufferStore EBX,ESI,ECX
Msg cc=C,'9314',SysGetEnvironment@RT ; Allocation error storing to buffer in !1H.
BufferStore EBX,=W(0),2
BufferRetrieve EBX
: Invoke EaBufferRelease::,EBX
; ESI is pointer to ASCIIZ variable name.
SUB ECX,ECX
WinAPI GetEnvironmentVariableA,ESI,ECX,ECX
MOV ECX,EAX ; Required value size.
TEST EAX
JZ .99:
MOV EDI,[ESP+44] ; OutEnvBuffer
BufferNew EDI,ECX
Msg cc=C,'9314',SysGetEnvironment@RT ; Allocation error storing to buffer in !1H.
JC .99:
WinAPI GetEnvironmentVariableA,ESI,EAX,ECX
BufferDecrement EDI
TEST EAX ; ZF=0 on success.
.99: POPAD
RET 12
ENDPROC1 SysGetEnvironment@RT:
%ENDMACRO SysGetEnvironment
Win (or Lin etc)
depending on OS which the EuroAssembler is compiled for.
SysGetEuroasmOS %MACRO EuroasmOSPtr
MOV EAX,"Win" ; OS version is hardwired here. Change it in ported versions.
%ENDMACRO SysGetEuroasmOS
euroasm.exe. The memory must be at least MAX_PATH_SIZE=260 bytes long.
SysGetExe %MACRO FilenamePtr
PUSH ECX,EDX
WinAPI GetModuleFileName,0,%1,MAX_PATH_SIZE
POP EDX,ECX
%ENDMACRO SysGetExe
Macro SysGetStackSize returns the amount of memory in bytes
reserved during linkage of the actually running euroasm.exe
. Obtained value will be used for protection from stack overflow error.
Stack in the loaded PECOFF executable is allocated in virtual address space somewhere below ImageBase but I didn't find a reliable way how to get its VA, so I read it from optional header in the loaded executable module.
SysGetStackSize %MACRO
PUSHAD
MOV EBX,1M ; Initialize SizeOfStackReserve with default value.
WinAPI GetModuleHandle,0
TEST EAX
STC
JZ .R%.:
CMPW [EAX+PFMZ_DOS_HEADER.e_magic],'MZ'
STC
JNE .R%.:
ADD EAX,[EAX+PFMZ_DOS_HEADER.e_lfanew] ; Get pointer to PE signature.
CMPD [EAX],'PE' ; EAX points to PE signature, file header and optional header.
STC
JNE .R%.:
CLC
MOV EBX,[EAX+4+SIZE#PFCOFF_FILE_HEADER+PFPE_OPTIONAL_HEADER.SizeOfStackReserve]
.R%.: MOV [ESP+28],EBX ; %ReturnEAX.
POPAD
%ENDMACRO SysGetStackSize
SysGetUTC %MACRO
CALL SysGetUTC@RT:
SysGetUTC@RT: PROC1
PUSH ECX,EDX,ESI,EDI
SUB ESP,8 + SIZE# SYSTEMTIME
MOV EDI,ESP ; EDI is pointer to FILETIME (QWORD).
LEA ESI,[ESP+8] ; ESI is pointer to SYSTEMTIME.
WinAPI GetSystemTime,ESI
WinAPI SystemTimeToFileTime,ESI,EDI
; FILETIME at EDI is now an unsigned integer QWORD with 100ns intervals elapsed since midnight 1.1.1601.
; 134774 days elapsed between 1.1.1601 and 1.1.1970,
; i.e. 134774*24*60*60*10000000=0x019DB1DE_D53E8000 must be subtracted from FILETIME at EDI.
MOV EAX,[EDI+0]
MOV EDX,[EDI+4]
SUB EAX,0xD53E8000
SBB EDX,0x019DB1DE
MOV ECX,10000000
DIV ECX
ADD ESP,8 + SIZE# SYSTEMTIME
POP EDI,ESI,EDX,ECX
RET
ENDPROC1 SysGetUTC@RT:
%ENDMACRO SysGetUTC
SysOpenFileMap %MACRO File, FileNamePtr, FileNameSize=-1
FileAssign %File, %FileNamePtr, Size=%FileNameSize
FileMapOpen %File
%ENDMACRO SysOpenFileMap
SysOutConsole %MACRO TextPtr, TextSize
%IF %# = 1 ; If only one parameter provided, use the max.integer value as text size.
PUSHD -1
%ELSE
PUSHD %TextSize
%ENDIF
PUSHD %TextPtr
CALL SysOutConsoleRT:
SysOutConsoleRT: PROC1
PUSHAD
MOV EBP,ESP
SUB ESP,SIZE# FILE
MOV EBX,ESP ; ^FILE.
MOV EDI,ESP
MOV ECX,SIZE# FILE / 4
XOR EAX,EAX
REP STOSD ; Clear the FILE.
FileAssign EBX,0 ; Standard output instead of filename.
FileCreate EBX ; Open the FILE for output.
MOV EDI,[EBP+36] ; %TextPtr.
MOV ECX,[EBP+40] ; %TextSize.
MOV ESI,EDI
JECXZ .Empty:
REPNE SCASB
SUB EDI,ESI
CMPB [ESI+EDI-1],0
JNZ .NZ:
DEC EDI ; EDI is now netto size of the text.
.NZ: FileWrite EBX,ESI,EDI
.Empty:MOV ESP,EBP
POPAD
RET 2*4
ENDPROC1 SysOutConsoleRT:
%ENDMACRO SysOutConsole
SysWriteFile %MACRO File, DataPtr, DataSize
FileWrite %File,%DataPtr,%DataSize
%ENDMACRO SysWriteFile
SysGetFileTime %MACRO FileNamePtr
MOV EAX,%FileNamePtr
CALL SysGetFileTime@RT:
SysGetFileTime@RT: PROC1
PUSH EBX,ECX,EDX,EDI
SUB ESP,8 ; Make room for FILETIME structure (QWORD).
MOV EDI,ESP
WinAPI CreateFile,EAX,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
MOV EBX,EAX
WinAPI GetFileTime,EBX,0,0,EDI
TEST EAX
JZ .80:
; FILETIME at EDI is now an unsigned integer QWORD with 100ns since midnight 1.1.1601.
; 134774 days elapsed between 1.1.1601 and 1.1.1970,
; i.e. 134774*24*60*60*10000000=0x019DB1DE_D53E8000 must be subtracted from FileTime at EDI.
MOV EAX,[EDI+0]
MOV EDX,[EDI+4]
SUB EAX,0xD53E8000
SBB EDX,0x019DB1DE
MOV ECX,10000000
DIV ECX
.80: ADD ESP,8
PUSH EAX
WinAPI CloseHandle,EBX
POP EAX
POP EDI,EDX,ECX,EBX
RET
ENDP1 SysGetFileTime@RT:
%ENDMACRO SysGetFileTime
SysGetFileSize %MACRO FileNamePtr
MOV EAX,%FileNamePtr
CALL SysGetFileSize@RT:
SysGetFileSize@RT: PROC1
PUSH EBX,ECX,EDI
SUB ESP,8 ; Make room for FileSize (QWORD).
LEA EDI,[ESP+4]
WinAPI CreateFile,EAX,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
MOV EBX,EAX
WinAPI GetFileSize,EBX,EDI
SUB EDI,4
MOV [EDI],EAX
INC EAX
JNZ .80:
WinAPI GetLastError
TEST EAX
JZ .80:
SUB EAX,EAX
MOV [EDI+0],EAX
MOV [EDI+4],EAX
.80: WinAPI CloseHandle,EBX
MOV EAX,[EDI+0]
MOV EDX,[EDI+4]
ADD ESP,8
POP EDI,ECX,EBX
RET
ENDP1 SysGetFileSize@RT:
%ENDMACRO SysGetFileSize
ENDHEAD syswin
ENDPROGRAM syswin