asmgens.pas

Переключить прокрутку окна
Загрузить этот исходный код

{
    Этот исходный текст является частью Продвинутого векторного транслятора.

    Copyright © 2017 Малик Разработчик

    Это свободная программа: вы можете перераспространять её и/или
    изменять её на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она может быть полезна,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <http://www.gnu.org/licenses/>.
}

unit AsmGens;

{$MODE DELPHI,EXTENDEDSYNTAX ON}

interface

uses
    Lang, Utils, GenX86;

type
    TextGenerator_16bit_DOS_COM = class;
    TextGenerator_32bit_GNULinux_ELF = class;
    TextGenerator_32bit_KolibriOS_MENUET01 = class;
    TextGenerator_32bit_Windows_Application = class;
    TextGenerator_32bit_Windows_GraphicApp = class;
    TextGenerator_32bit_Windows_ConsoleApp = class;
    TextGenerator_64bit_GNULinux_ELF = class;
    TextGenerator_64bit_Windows_Application = class;
    TextGenerator_64bit_Windows_GraphicApp = class;
    TextGenerator_64bit_Windows_ConsoleApp = class;

    TextGenerator_16bit_DOS_COM = class(TextGenerator)
    public
        class function isNeedHeapSize(): boolean; override;
        class function isNeedStackSize(): boolean; override;
        class function isNeedExitMethod(): boolean; override;

    public
        constructor create(); override;
	end;

    TextGenerator_32bit_GNULinux_ELF = class(TextGenerator)
    public
        class function isNeedExitMethod(): boolean; override;

    public
        constructor create(); override;
        procedure beginCodeSection(); override;
        procedure beginDataSection(); override;
        procedure beginPoolSection(); override;
        procedure writeDirectives(mode, org: int; const entry: String); override;
    protected
        procedure setExitMethod(exitMethod: int); override;
	end;

    TextGenerator_32bit_KolibriOS_MENUET01 = class(TextGenerator)
    public
        class function isNeedHeapSize(): boolean; override;
        class function isNeedStackSize(): boolean; override;
        class function isNeedExitMethod(): boolean; override;
    protected
        const STACK_SIZE = 'STACK_SIZE';
        const HEAP_SIZE = 'HEAP_SIZE';
        const CMD_SIZE = 'CMD_SIZE';
        const PROG_BEGIN = 'PROG_BEGIN';
        const PROG_END = 'PROG_END';
        const HEAP_BEGIN = 'HEAP_BEGIN';
        const HEAP_END = 'HEAP_END';
        const RUN_PATH = 'RUN_PATH';
        const CMD_LINE = 'CMD_LINE';

    public
        constructor create(); override;
        procedure writeDirectives(mode, org: int; const entry: String); override;
        procedure writeProgrammeTail(); override;
    protected
        procedure setHeapSize(heapSize: int); override;
        procedure setStackSize(stackSize: int); override;
        procedure setExitMethod(exitMethod: int); override;
   	end;

    TextGenerator_32bit_Windows_Application = class(TextGenerator)
    public
        class function isNeedHeapSize(): boolean; override;
        class function isNeedStackSize(): boolean; override;
        class function isNeedExitMethod(): boolean; override;

    public
        constructor create(); override;
        procedure beginCodeSection(); override;
        procedure beginDataSection(); override;
        procedure beginPoolSection(); override;
    protected
        procedure setHeapSize(heapSize: int); override;
        procedure setStackSize(stackSize: int); override;
        procedure setExitMethod(exitMethod: int); override;
        procedure writeExeAttr(const entry: String); virtual;
	end;

    TextGenerator_32bit_Windows_GraphicApp = class(TextGenerator_32bit_Windows_Application)
    public
        procedure writeDirectives(mode, org: int; const entry: String); override;
	end;

    TextGenerator_32bit_Windows_ConsoleApp = class(TextGenerator_32bit_Windows_Application)
    public
        procedure writeDirectives(mode, org: int; const entry: String); override;
	end;

    TextGenerator_64bit_GNULinux_ELF = class(TextGenerator64)
    public
        class function isNeedExitMethod(): boolean; override;

    public
        constructor create(); override;
        procedure beginCodeSection(); override;
        procedure beginDataSection(); override;
        procedure beginPoolSection(); override;
        procedure writeDirectives(mode, org: int; const entry: String); override;
    protected
        procedure setExitMethod(exitMethod: int); override;
    end;

    TextGenerator_64bit_Windows_Application = class(TextGenerator64)
    public
        class function isNeedHeapSize(): boolean; override;
        class function isNeedStackSize(): boolean; override;
        class function isNeedExitMethod(): boolean; override;

    public
        constructor create(); override;
        procedure beginCodeSection(); override;
        procedure beginDataSection(); override;
        procedure beginPoolSection(); override;
    protected
        procedure setHeapSize(heapSize: int); override;
        procedure setStackSize(stackSize: int); override;
        procedure setExitMethod(exitMethod: int); override;
        procedure writeExeAttr(const entry: String); virtual;
	end;

    TextGenerator_64bit_Windows_GraphicApp = class(TextGenerator_64bit_Windows_Application)
    public
        procedure writeDirectives(mode, org: int; const entry: String); override;
	end;

    TextGenerator_64bit_Windows_ConsoleApp = class(TextGenerator_64bit_Windows_Application)
    public
        procedure writeDirectives(mode, org: int; const entry: String); override;
	end;

implementation

{ TextGenerator_16bit_DOS_COM }

class function TextGenerator_16bit_DOS_COM.isNeedHeapSize(): boolean;
begin
	result := false;
end;

class function TextGenerator_16bit_DOS_COM.isNeedStackSize(): boolean;
begin
	result := false;
end;

class function TextGenerator_16bit_DOS_COM.isNeedExitMethod(): boolean;
begin
	result := false;
end;

constructor TextGenerator_16bit_DOS_COM.create();
begin
	inherited create();
    self.fldExitMethod := EXIT_RET;
end;

{ TextGenerator_32bit_GNULinux_ELF }

class function TextGenerator_32bit_GNULinux_ELF.isNeedExitMethod(): boolean;
begin
	result := false;
end;

constructor TextGenerator_32bit_GNULinux_ELF.create();
begin
	inherited create();
    self.fldExitMethod := EXIT_CALL;
end;

procedure TextGenerator_32bit_GNULinux_ELF.beginCodeSection();
begin
	{writeText('segment readable executable');}
    {writeEmptyLine();}
end;

procedure TextGenerator_32bit_GNULinux_ELF.beginDataSection();
begin
	{writeText('segment readable writable');}
    {writeEmptyLine();}
end;

procedure TextGenerator_32bit_GNULinux_ELF.beginPoolSection();
begin
	{writeText('segment readable');}
    {writeEmptyLine();}
end;

procedure TextGenerator_32bit_GNULinux_ELF.writeDirectives(mode, org: int; const entry: String);
begin
	writeText('format ELF executable 3');
    writeInstruction('entry', entry);
    inherited writeDirectives(MODE_NONE, 0, '');
end;

procedure TextGenerator_32bit_GNULinux_ELF.setExitMethod(exitMethod: int);
begin
	raise UnsupportedOperationException.create(msgUnsupportedOperation);
end;

{ TextGenerator_32bit_KolibriOS_MENUET01 }

class function TextGenerator_32bit_KolibriOS_MENUET01.isNeedHeapSize(): boolean;
begin
	result := true;
end;

class function TextGenerator_32bit_KolibriOS_MENUET01.isNeedStackSize(): boolean;
begin
	result := true;
end;

class function TextGenerator_32bit_KolibriOS_MENUET01.isNeedExitMethod(): boolean;
begin
	result := false;
end;

constructor TextGenerator_32bit_KolibriOS_MENUET01.create();
begin
    inherited create();
    self.fldExitMethod := EXIT_CALL;
    setHeapSize($00010000);
    setStackSize($00001000);
end;

procedure TextGenerator_32bit_KolibriOS_MENUET01.writeDirectives(mode, org: int;
        const entry: String);
begin
	inherited writeDirectives(mode, org, entry);
    writeEmptyLine();
    writeEquality(STACK_SIZE, #$09'(((' + immediateToStringShort($1000) +
            (' - ' + PROG_END + ') and ') + immediateToStringShort($0fff) + ') + \');
    writeInstruction(immediateToStringInt(getStackSize()) + ')');
    writeCommentToLineEnd('<- минимальный размер стека (в байтах) прописывается здесь');
    writeEquality(HEAP_SIZE, #$09 + immediateToStringInt(getHeapSize()));
    writeCommentToLineEnd(' <- общий объём кучи (в байтах) прописывается здесь');
    writeEquality(CMD_SIZE, #$09 + immediateToString($0800));
    writeEmptyLine();
    writeLabelLong(PROG_BEGIN);
    writeCommentToLineEnd('магическое число');
    writeInstruction('db', '''MENUET01''');
    writeEmptyLine();
    writeCommentWithIdent('версия заголовка (всегда 1)');
    writeInstruction('dd', immediateToStringInt(1));
    writeEmptyLine();
    writeCommentWithIdent('точка входа в программу');
    writeInstruction('dd', entry);
    writeEmptyLine();
    writeCommentWithIdent('размер программы (в байтах)');
    writeInstruction('dd', PROG_END + ' - ' + PROG_BEGIN);
    writeEmptyLine();
    writeCommentWithIdent('количество необходимой программе памяти (в байтах)');
    writeInstruction('dd', PROG_END + ' + ' + STACK_SIZE + ' + ' +
            HEAP_SIZE + ' + ' + CMD_SIZE + ' + ' + CMD_SIZE);
    writeEmptyLine();
    writeCommentWithIdent('начальное значение регистра esp (вершина стека)');
    writeLabelLong(HEAP_BEGIN);
    writeInstruction('dd', PROG_END + ' + ' + STACK_SIZE);
    writeEmptyLine();
    writeLabelLong(HEAP_END);
    writeCommentWithIdent('сюда операционная система запишет ссылку на строку параметров');
    writeLabelLong(CMD_LINE);
    writeInstruction('dd', PROG_END + ' + ' + STACK_SIZE + ' + ' + HEAP_SIZE);
    writeEmptyLine();
    writeLabelLong(RUN_PATH);
    writeCommentWithIdent('сюда операционная система запишет ссылку на путь запуска');
    writeInstruction('dd', PROG_END + ' + ' + STACK_SIZE + ' + ' + HEAP_SIZE + ' + ' + CMD_SIZE);
end;

procedure TextGenerator_32bit_KolibriOS_MENUET01.writeProgrammeTail();
begin
    writeLabelLong(PROG_END);
    writeEmptyLine();
	inherited writeProgrammeTail();
end;

procedure TextGenerator_32bit_KolibriOS_MENUET01.setHeapSize(heapSize: int);
begin
	inherited setHeapSize(heapSize + ((8 - heapSize) and 7));
end;

procedure TextGenerator_32bit_KolibriOS_MENUET01.setStackSize(stackSize: int);
begin
	inherited setStackSize(stackSize + ((4 - stackSize) and 3));
end;

procedure TextGenerator_32bit_KolibriOS_MENUET01.setExitMethod(exitMethod: int);
begin
	raise UnsupportedOperationException.create(msgUnsupportedOperation);
end;

{ TextGenerator_32bit_Windows_Application }

class function TextGenerator_32bit_Windows_Application.isNeedHeapSize(): boolean;
begin
	result := true;
end;

class function TextGenerator_32bit_Windows_Application.isNeedStackSize(): boolean;
begin
	result := true;
end;

class function TextGenerator_32bit_Windows_Application.isNeedExitMethod(): boolean;
begin
	result := false;
end;

constructor TextGenerator_32bit_Windows_Application.create();
begin
	inherited create();
    self.fldExitMethod := EXIT_CALL;
    setHeapSize($00010000);
    setStackSize($00001000);
end;

procedure TextGenerator_32bit_Windows_Application.beginCodeSection();
begin
    writeText('section ".func" code readable executable');
    writeEmptyLine();
end;

procedure TextGenerator_32bit_Windows_Application.beginDataSection();
begin
    writeText('section ".gvar" data readable writable');
    writeEmptyLine();
end;

procedure TextGenerator_32bit_Windows_Application.beginPoolSection();
begin
    writeText('section ".pool" data readable');
    writeEmptyLine();
end;

procedure TextGenerator_32bit_Windows_Application.setHeapSize(heapSize: int);
begin
	inherited setHeapSize(heapSize + ((8 - heapSize) and 7));
end;

procedure TextGenerator_32bit_Windows_Application.setStackSize(stackSize: int);
begin
	inherited setStackSize(stackSize + ((8 - stackSize) and 7));
end;

procedure TextGenerator_32bit_Windows_Application.setExitMethod(exitMethod: int);
begin
	raise UnsupportedOperationException.create(msgUnsupportedOperation);
end;

procedure TextGenerator_32bit_Windows_Application.writeExeAttr(const entry: String);
begin
    writeInstruction('entry', entry);
    writeInstruction('stack', immediateToStringInt(stackSize));
    writeInstruction('heap', immediateToStringInt(heapSize));
end;

{ TextGenerator_32bit_Windows_GraphicApp }

procedure TextGenerator_32bit_Windows_GraphicApp.writeDirectives(mode, org: int;
		const entry: String);
begin
    writeText('format PE GUI 4.0');
    writeExeAttr(entry);
	inherited writeDirectives(MODE_NONE, 0, '');
end;

{ TextGenerator_32bit_Windows_ConsoleApp }

procedure TextGenerator_32bit_Windows_ConsoleApp.writeDirectives(mode, org: int;
		const entry: String);
begin
    writeText('format PE console 4.0');
    writeExeAttr(entry);
	inherited writeDirectives(MODE_NONE, 0, '');
end;

{ TextGenerator_64bit_GNULinux_ELF }

class function TextGenerator_64bit_GNULinux_ELF.isNeedExitMethod(): boolean;
begin
	result := false;
end;

constructor TextGenerator_64bit_GNULinux_ELF.create();
begin
	inherited create();
    self.fldExitMethod := EXIT_CALL;
end;

procedure TextGenerator_64bit_GNULinux_ELF.beginCodeSection();
begin
	{writeText('segment readable executable');}
    {writeEmptyLine();}
end;

procedure TextGenerator_64bit_GNULinux_ELF.beginDataSection();
begin
	{writeText('segment readable writable');}
    {writeEmptyLine();}
end;

procedure TextGenerator_64bit_GNULinux_ELF.beginPoolSection();
begin
	{writeText('segment readable');}
    {writeEmptyLine();}
end;

procedure TextGenerator_64bit_GNULinux_ELF.writeDirectives(mode, org: int; const entry: String);
begin
	writeText('format ELF64 executable 3');
    writeInstruction('entry', entry);
    inherited writeDirectives(MODE_NONE, 0, '');
end;

procedure TextGenerator_64bit_GNULinux_ELF.setExitMethod(exitMethod: int);
begin
	raise UnsupportedOperationException.create(msgUnsupportedOperation);
end;

{ TextGenerator_64bit_Windows_Application }

class function TextGenerator_64bit_Windows_Application.isNeedHeapSize(): boolean;
begin
	result := true;
end;

class function TextGenerator_64bit_Windows_Application.isNeedStackSize(): boolean;
begin
	result := true;
end;

class function TextGenerator_64bit_Windows_Application.isNeedExitMethod(): boolean;
begin
	result := false;
end;

constructor TextGenerator_64bit_Windows_Application.create();
begin
	inherited create();
    self.fldExitMethod := EXIT_CALL;
    setHeapSize($00010000);
    setStackSize($00001000);
end;

procedure TextGenerator_64bit_Windows_Application.beginCodeSection();
begin
    writeText('section ".func" code readable executable');
    writeEmptyLine();
end;

procedure TextGenerator_64bit_Windows_Application.beginDataSection();
begin
    writeText('section ".gvar" data readable writable');
    writeEmptyLine();
end;

procedure TextGenerator_64bit_Windows_Application.beginPoolSection();
begin
    writeText('section ".pool" data readable');
    writeEmptyLine();
end;

procedure TextGenerator_64bit_Windows_Application.setHeapSize(heapSize: int);
begin
	inherited setHeapSize(heapSize + ((8 - heapSize) and 7));
end;

procedure TextGenerator_64bit_Windows_Application.setStackSize(stackSize: int);
begin
	inherited setStackSize(stackSize + ((8 - stackSize) and 7));
end;

procedure TextGenerator_64bit_Windows_Application.setExitMethod(exitMethod: int);
begin
	raise UnsupportedOperationException.create(msgUnsupportedOperation);
end;

procedure TextGenerator_64bit_Windows_Application.writeExeAttr(const entry: String);
begin
    writeInstruction('entry', entry);
    writeInstruction('stack', immediateToStringInt(stackSize));
    writeInstruction('heap', immediateToStringInt(heapSize));
end;

{ TextGenerator_64bit_Windows_GraphicApp }

procedure TextGenerator_64bit_Windows_GraphicApp.writeDirectives(mode, org: int;
		const entry: String);
begin
    writeText('format PE64 GUI 5.0');
    writeExeAttr(entry);
	inherited writeDirectives(MODE_NONE, 0, '');
end;

{ TextGenerator_64bit_Windows_ConsoleApp }

procedure TextGenerator_64bit_Windows_ConsoleApp.writeDirectives(mode, org: int;
		const entry: String);
begin
    writeText('format PE64 console 5.0');
    writeExeAttr(entry);
	inherited writeDirectives(MODE_NONE, 0, '');
end;

end.