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. INCLUDEHEAD ea.htm, eaopt.htm, msg.htm, pgmopt.htm ; Include headers of another modules used in this module.
syswin HEAD ; Start of interface, which is included to other modules. INCLUDEHEAD1 winapi.htm, wins.htm, winscon.htm, winstime.htm, winsfile.htm, winf32.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_HEADER32.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