Files
Work/common/CODEGEN.HPP
2024-08-07 09:09:36 -04:00

919 lines
14 KiB
C++

#ifndef _COMMON_CODEGEN_HPP_
#define _COMMON_CODEGEN_HPP_
#include <common/stdio.hpp>
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_FILEMAP_HPP_
#include <common/filemap.hpp>
#endif
#ifndef _COMMON_PUREVIEWOFFILE_HPP_
#include <common/pview.hpp>
#endif
#ifndef _COMMON_GLOBALDATA_HPP_
#include <common/gdata.hpp>
#endif
#if defined(_MSC_VER)
#pragma warning(disable:4355)
#endif
class CodeGen : public FileMap, public PureViewOfFile
{
public:
CodeGen(DWORD maxExtent=100000L);
virtual ~CodeGen();
void breakPoint(void);
void nop(void);
void pushDS(void);
void popDS(void);
void pushCS(void);
void movEAXOFFSETDS(int dsOffset);
void movOFFSETDSEAX(int dsOffset);
void pushad(void);
void popad(void);
void pushOFFSETCS(int csOffset);
void pushEAX(void);
void pushECX(void);
void pushEBP(void);
void pushESP(void);
void pushEDI(void);
void pushESI(void);
void push(int value);
void popEBP(void);
void popESP(void);
void popESI(void);
void popEDI(void);
void popAX(void);
void popEAX(void);
void popEBX(void);
void popECX(void);
void pushEBX(void);
void subEDI(BYTE byteCount);
void subESP(BYTE byteCount);
void movDHDL(void);
void movEDIDX(void);
void movAXCS(void);
void movEAXEBX(void);
void movEBXEAX(void);
void movEBPESP(void);
void movECXESI(void);
void movECXEDI(void);
void movESIEBP(BYTE stackIndex);
void movEDIEBP(BYTE stackIndex);
void movEAXEBP(BYTE stackIndex);
void movEAXESP(BYTE stackIndex);
void movEAXEBP(void);
void movEAXESP(void);
void movAXEBP(BYTE stackIndex);
void movBXEBP(BYTE stackIndex);
void movCXEBP(BYTE stackIndex);
void movDXEBP(BYTE stackIndex);
void movALESI(LONG sourceIndex);
void movESIAL(LONG sourceIndex);
void movDLESI(DWORD sourceIndex);
void movEDIDX(LONG offset);
void movEDIDL(LONG offset);
void movEDIAL(LONG offset);
void movEDIDL(void);
void movCLEBP(BYTE stackIndex);
void movOFFSETESI(BYTE offset,BYTE charByte);
void movEAXOFFSETCS(int csOffset);
void movECXOFFSETCS(int csOffset);
void movEAXOFFSETSS(int offset);
void movOFFSETSSEAX(int offset);
void movEAXESPOFFSET(int offset);
void movEAXEBPOFFSET(int offset);
void movESPOFFSETEAX(int offset);
void movESPOFFSETEBX(int offset);
void movDEREFEAXEBX(void);
void leaESIEBP(BYTE offset);
void addEDIEAX(void);
void addEDIEBP(BYTE stackIndex);
void addESP(int value);
void addEAX(int value);
void addEBP(int value);
void subEAX(int value);
void xorEAXEAX(void);
void call(int offset);
void callEBP(BYTE offset);
void callEAX(void);
void callEBX(void);
void callECX(void);
void je(BYTE jumpCount);
void jmp(BYTE jumpBytes);
void jnl(BYTE jumpCount);
void cmpALCL(void);
void decEDI(void);
void movEAX(int value);
void movECX(int value);
void pushEBPEAXPLUS(int eaxAdditive);
void decEAX(void);
void cmpEAX(int value);
void pushFSOFFSET(WORD offset);
void movFSOFFSETESP(WORD offset);
void movFSOFFSETEAX(int offset);
void retn(void);
void retn(short stackLength);
void retf(void);
void intno(BYTE intno);
void encodeDD(int value=0);
void encodeDB(BYTE value=0);
void wait(void);
void finit(void);
void execute(void);
void debugExecute(void);
private:
String entryName(void)const;
};
inline
CodeGen::CodeGen(DWORD maxExtent)
: FileMap(entryName(),0L,1024), PureViewOfFile((FileMap&)*this)
{
}
inline
CodeGen::~CodeGen()
{
}
inline
void CodeGen::breakPoint(void)
{
write((BYTE)(0xCC));
}
inline
void CodeGen::pushOFFSETCS(int csOffset)
{
write((BYTE)(0x2E));
write((BYTE)(0xFF));
write((BYTE)(0x35));
write(csOffset);
}
inline
void CodeGen::pushad(void)
{
write((BYTE)(0x60));
}
inline
void CodeGen::popad(void)
{
write((BYTE)(0x61));
}
inline
void CodeGen::pushEAX(void)
{
write((BYTE)(0x50));
}
inline
void CodeGen::pushECX(void)
{
write((BYTE)(0x51));
}
inline
void CodeGen::popECX(void)
{
write((BYTE)(0x59));
}
inline
void CodeGen::pushEBP(void)
{
write((BYTE)(0x55));
}
inline
void CodeGen::pushESP(void)
{
write((BYTE)(0x54));
}
inline
void CodeGen::pushEDI(void)
{
write((BYTE)(0x57));
}
inline
void CodeGen::pushESI(void)
{
write((BYTE)(0x56));
}
inline
void CodeGen::popEBP(void)
{
write((BYTE)(0x5D));
}
inline
void CodeGen::popESP(void)
{
write((BYTE)(0x5C));
}
inline
void CodeGen::popESI(void)
{
write((BYTE)(0x5E));
}
inline
void CodeGen::popEDI(void)
{
write((BYTE)(0x5F));
}
inline
void CodeGen::popAX(void)
{
write((BYTE)(0x66));
write((BYTE)(0x58));
}
inline
void CodeGen::movEBPESP(void)
{
write((BYTE)(0x8B));
write((BYTE)(0xEC));
}
inline
void CodeGen::movESIEBP(BYTE stackIndex)
{
write((BYTE)(0x8B));
write((BYTE)(0x75));
write(stackIndex);
}
inline
void CodeGen::movEDIEBP(BYTE stackIndex)
{
write((BYTE)(0x8B));
write((BYTE)(0x7D));
write(stackIndex);
}
inline
void CodeGen::movEAXEBP(BYTE stackIndex)
{
write((BYTE)(0x8B));
write((BYTE)(0x45));
write(stackIndex);
}
inline
void CodeGen::movEAXESP(BYTE stackIndex)
{
write((BYTE)(0x8B));
write((BYTE)(0x44));
write((BYTE)(0x24));
write(stackIndex);
}
inline
void CodeGen::movEAXEBP(void)
{
write((BYTE)(0x8B));
write((BYTE)(0xC5));
}
inline
void CodeGen::movEDIDL(void)
{
write((BYTE)(0x88));
write((BYTE)(0x17));
}
inline
void CodeGen::decEDI(void)
{
write((BYTE)(0x4F));
}
inline
void CodeGen::addEDIEAX(void)
{
write((BYTE)(0x03));
write((BYTE)(0xF8));
}
inline
void CodeGen::addEDIEBP(BYTE stackIndex)
{
write((BYTE)(0x03));
write((BYTE)(0x7D));
write(stackIndex);
}
inline
void CodeGen::retn(void)
{
write((BYTE)(0xC3));
}
inline
void CodeGen::retn(short stackLength)
{
write((BYTE)(0xC2));
write(stackLength);
}
inline
void CodeGen::retf(void)
{
write((BYTE)(0xCB));
}
inline
void CodeGen::movDLESI(DWORD sourceIndex)
{
write((BYTE)(0x8A));
write((BYTE)(0x96));
write((BYTE)(sourceIndex&0x000000FF));
write((BYTE)((sourceIndex&0x0000FF00)>>0x08));
write((BYTE)((sourceIndex&0x00FF0000)>>0x10));
write((BYTE)((sourceIndex&0xFF000000)>>0x18));
}
inline
void CodeGen::movDHDL(void)
{
write((BYTE)(0x8A));
write((BYTE)(0xF2));
}
inline
void CodeGen::movOFFSETESI(BYTE offset,BYTE charByte)
{
write((BYTE)(0xC6));
write((BYTE)(0x46));
write(offset);
write(charByte);
}
inline
void CodeGen::subEDI(BYTE byteCount)
{
write((BYTE)(0x83));
write((BYTE)(0xEF));
write(byteCount);
}
inline
void CodeGen::subESP(BYTE byteCount)
{
write((BYTE)(0x83));
write((BYTE)(0xEC));
write(byteCount);
}
inline
void CodeGen::movEDIDX(void)
{
write((BYTE)(0x66));
write((BYTE)(0x89));
write((BYTE)(0x17));
}
inline
void CodeGen::movEDIDX(LONG sourceIndex)
{
write((BYTE)(0x66));
write((BYTE)(0x89));
write((BYTE)(0x97));
write((BYTE)(sourceIndex&0x000000FF));
write((BYTE)((sourceIndex&0x0000FF00)>>0x08));
write((BYTE)((sourceIndex&0x00FF0000)>>0x10));
write((BYTE)((sourceIndex&0xFF000000)>>0x18));
}
inline
void CodeGen::movEDIDL(LONG sourceIndex)
{
write((BYTE)(0x88));
write((BYTE)(0x97));
write((BYTE)(sourceIndex&0x000000FF));
write((BYTE)((sourceIndex&0x0000FF00)>>0x08));
write((BYTE)((sourceIndex&0x00FF0000)>>0x10));
write((BYTE)((sourceIndex&0xFF000000)>>0x18));
}
inline
void CodeGen::movALESI(LONG sourceIndex)
{
write((BYTE)(0x8A));
write((BYTE)(0x86));
write((BYTE)(sourceIndex&0x000000FF));
write((BYTE)((sourceIndex&0x0000FF00)>>0x08));
write((BYTE)((sourceIndex&0x00FF0000)>>0x10));
write((BYTE)((sourceIndex&0xFF000000)>>0x18));
}
inline
void CodeGen::movESIAL(LONG sourceIndex)
{
write((BYTE)(0x88));
write((BYTE)(0x86));
write((BYTE)(sourceIndex&0x000000FF));
write((BYTE)((sourceIndex&0x0000FF00)>>0x08));
write((BYTE)((sourceIndex&0x00FF0000)>>0x10));
write((BYTE)((sourceIndex&0xFF000000)>>0x18));
}
inline
void CodeGen::movEDIAL(LONG sourceIndex)
{
write((BYTE)(0x88));
write((BYTE)(0x87));
write((BYTE)(sourceIndex&0x000000FF));
write((BYTE)((sourceIndex&0x0000FF00)>>0x08));
write((BYTE)((sourceIndex&0x00FF0000)>>0x10));
write((BYTE)((sourceIndex&0xFF000000)>>0x18));
}
inline
void CodeGen::movAXCS(void)
{
write((BYTE)(0x66));
write((BYTE)(0x8C));
write((BYTE)(0xC8));
}
inline
void CodeGen::movCLEBP(BYTE stackIndex)
{
write((BYTE)(0x8A));
write((BYTE)(0x4D));
write(stackIndex);
}
inline
void CodeGen::leaESIEBP(BYTE offset)
{
write((BYTE)(0x8D));
write((BYTE)(0x75));
write(offset);
}
inline
void CodeGen::cmpALCL(void)
{
write((BYTE)(0x3A));
write((BYTE)(0xC1));
}
inline
void CodeGen::call(int offset)
{
write((BYTE)(0xE8));
write(offset);
}
inline
void CodeGen::callEBP(BYTE offset)
{
write((BYTE)(0xFF));
write((BYTE)(0x55));
write(offset);
}
inline
void CodeGen::callEAX(void)
{
write((BYTE)(0xFF));
write((BYTE)(0xD0));
}
inline
void CodeGen::callEBX(void)
{
write((BYTE)(0xFF));
write((BYTE)(0xD3));
}
inline
void CodeGen::callECX(void)
{
write((BYTE)(0xFF));
write((BYTE)(0xD1));
}
inline
void CodeGen::je(BYTE jumpCount)
{
write((BYTE)(0x74));
write(jumpCount);
}
inline
void CodeGen::jmp(BYTE jumpCount)
{
write((BYTE)(0xEB));
write(jumpCount);
}
inline
void CodeGen::jnl(BYTE jumpCount)
{
write((BYTE)(0x7D));
write(jumpCount);
}
inline
void CodeGen::intno(BYTE intno)
{
write((BYTE)(0xCD));
write(intno);
}
inline
void CodeGen::movAXEBP(BYTE stackIndex)
{
write((BYTE)(0x66));
write((BYTE)(0x8B));
write((BYTE)(0x45));
write(stackIndex);
}
inline
void CodeGen::movBXEBP(BYTE stackIndex)
{
write((BYTE)(0x66));
write((BYTE)(0x8B));
write((BYTE)(0x5D));
write(stackIndex);
}
inline
void CodeGen::movCXEBP(BYTE stackIndex)
{
write((BYTE)(0x66));
write((BYTE)(0x8B));
write((BYTE)(0x4D));
write(stackIndex);
}
inline
void CodeGen::movDXEBP(BYTE stackIndex)
{
write((BYTE)(0x66));
write((BYTE)(0x8B));
write((BYTE)(0x55));
write(stackIndex);
}
inline
void CodeGen::xorEAXEAX(void)
{
write((BYTE)(0x33));
write((BYTE)(0xC0));
}
inline
void CodeGen::push(int value)
{
write((BYTE)(0x68));
write(value);
}
inline
void CodeGen::popEAX(void)
{
write((BYTE)(0x58));
}
inline
void CodeGen::addESP(int value)
{
write((BYTE)(0x81));
write((BYTE)(0xC4));
write(value);
}
inline
void CodeGen::addEAX(int value)
{
write((BYTE)(0x05));
write(value);
}
inline
void CodeGen::subEAX(int value)
{
write((BYTE)(0x2D));
write(value);
}
inline
void CodeGen::encodeDD(int value)
{
write(value);
}
inline
void CodeGen::encodeDB(BYTE value)
{
write(value);
}
inline
void CodeGen::execute(void)
{
(*((FARPROC)((BYTE*)base())))();
}
inline
void CodeGen::debugExecute(void)
{
GlobalData<BYTE> code;
code.size(tell()+1);
::memcpy((BYTE*)&code[0],(BYTE*)base(),tell()+1);
(*((FARPROC)((BYTE*)&code[0])))();
}
inline
String CodeGen::entryName(void)const
{
String entryPointName;
::sprintf(entryPointName,"CODE%08lx.BIN",(DWORD)this);
return entryPointName;
}
inline
void CodeGen::movEAXOFFSETCS(int csOffset) // mov eax,cs:[csOffset]
{
write((BYTE)(0x2E));
write((BYTE)(0xA1));
write(csOffset);
}
inline
void CodeGen::movECXOFFSETCS(int csOffset) // mov ecx,cs:[csOffset]
{
write((BYTE)(0x2E));
write((BYTE)(0x8B));
write((BYTE)(0x0D));
write(csOffset);
}
inline
void CodeGen::pushDS(void)
{
write((BYTE)(0x1E));
}
inline
void CodeGen::popDS(void)
{
write((BYTE)(0x1F));
}
inline
void CodeGen::pushCS(void)
{
write((BYTE)(0x0E));
}
inline
void CodeGen::movEAXOFFSETDS(int dsOffset)
{
write((BYTE)(0xA1));
write(dsOffset);
}
inline
void CodeGen::movOFFSETDSEAX(int dsOffset)
{
write((BYTE)(0xA3));
write(dsOffset);
}
inline
void CodeGen::nop(void)
{
write((BYTE)(0x90));
}
inline
void CodeGen::movEAXEBX(void) // mov eax,ebx
{
write((BYTE)(0x8B));
write((BYTE)(0xC3));
}
inline
void CodeGen::movEBXEAX(void) // mov ebx,eax
{
write((BYTE)(0x8B));
write((BYTE)(0xD8));
}
inline
void CodeGen::popEBX(void)
{
write((BYTE)(0x5B));
}
inline
void CodeGen::pushEBX(void)
{
write((BYTE)(0x53));
}
inline
void CodeGen::movEAX(int value)
{
write((BYTE)(0xB8));
write(value);
}
inline
void CodeGen::pushEBPEAXPLUS(int eaxAdditive)
{
write((BYTE)(0xFF));
write((BYTE)(0xB4));
write((BYTE)(0x05));
write(eaxAdditive);
}
inline
void CodeGen::decEAX(void)
{
write((BYTE)(0x48));
}
inline
void CodeGen::cmpEAX(int value)
{
write((BYTE)(0x3D));
write(value);
}
inline
void CodeGen::addEBP(int value)
{
write((BYTE)(0x81));
write((BYTE)(0xC5));
write(value);
}
inline
void CodeGen::movECXESI(void)
{
write((BYTE)(0x8B));
write((BYTE)(0xCE));
}
inline
void CodeGen::movECXEDI(void)
{
write((BYTE)(0x8B));
write((BYTE)(0xCF));
}
inline
void CodeGen::movECX(int value)
{
write((BYTE)(0xB9));
write(value);
}
inline
void CodeGen::movEAXESP(void)
{
write((BYTE)(0x8B));
write((BYTE)(0xC4));
}
inline
void CodeGen::pushFSOFFSET(WORD offset)
{
write((BYTE)(0x64));
write((BYTE)(0x67));
write((BYTE)(0xFF));
write((BYTE)(0X36));
write((BYTE)(offset&0x00FF));
write((BYTE)(offset>>0x08));
}
inline
void CodeGen::movFSOFFSETESP(WORD offset)
{
write((BYTE)(0x64));
write((BYTE)(0x67));
write((BYTE)(0x89));
write((BYTE)(0x26));
write((BYTE)(offset&0x00FF));
write((BYTE)(offset>>0x08));
}
inline
void CodeGen::movEAXOFFSETSS(int offset)
{
write((BYTE)(0x36));
write((BYTE)(0xA1));
write((BYTE)(offset));
write((BYTE)(offset>>0x08));
write((BYTE)(offset>>0x10));
write((BYTE)(offset>>0x18));
}
inline
void CodeGen::movOFFSETSSEAX(int offset)
{
write((BYTE)(0x36));
write((BYTE)(0xA3));
write((BYTE)(offset));
write((BYTE)(offset>>0x08));
write((BYTE)(offset>>0x10));
write((BYTE)(offset>>0x18));
}
inline
void CodeGen::movEAXESPOFFSET(int offset)
{
write((BYTE)(0x8B));
write((BYTE)(0x84));
write((BYTE)(0x24));
write((BYTE)(offset));
write((BYTE)(offset>>0x08));
write((BYTE)(offset>>0x10));
write((BYTE)(offset>>0x18));
}
inline
void CodeGen::movEAXEBPOFFSET(int offset)
{
write((BYTE)(0x8B));
write((BYTE)(0x85));
write((BYTE)(0x56));
write((BYTE)(offset));
write((BYTE)(offset>>0x08));
write((BYTE)(offset>>0x10));
write((BYTE)(offset>>0x18));
}
inline
void CodeGen::movESPOFFSETEAX(int offset)
{
write((BYTE)(0x89));
write((BYTE)(0x84));
write((BYTE)(0x24));
write((BYTE)(offset));
write((BYTE)(offset>>0x08));
write((BYTE)(offset>>0x10));
write((BYTE)(offset>>0x18));
}
inline
void CodeGen::movFSOFFSETEAX(int offset)
{
write((BYTE)(0x64));
write((BYTE)(0xA3));
write((BYTE)(offset));
write((BYTE)(offset>>0x08));
write((BYTE)(offset>>0x10));
write((BYTE)(offset>>0x18));
}
inline
void CodeGen::movESPOFFSETEBX(int offset)
{
write((BYTE)(0x89));
write((BYTE)(0x9C));
write((BYTE)(0x24));
write((BYTE)(offset));
write((BYTE)(offset>>0x08));
write((BYTE)(offset>>0x10));
write((BYTE)(offset>>0x18));
}
inline
void CodeGen::movDEREFEAXEBX(void)
{
write((BYTE)(0x89));
write((BYTE)(0x18));
}
inline
void CodeGen::wait(void)
{
write((BYTE)0x9B);
}
inline
void CodeGen::finit(void)
{
write((BYTE)0xDB);
write((BYTE)0xE3);
}
#endif