DAK. Pascal (Delphi) => Fasm

High-level languages programming questions
  • Краткое описание-черновик DAK. Возможности DAKа.
    Точнее говоря, пока еще скудные возможности DAKа.

    Комментарии в DAK.
    В DAK организация комментариев такая же как и у Delphi, - '{…}', '(*…*)' или '//..... (до конца строки)'

    Секция модуля.
    В секции модуля можно определять глобальные, целочисленные константы, разменом не более Cardinal (0..4294967295). Константа должна быть без всяких «+» или «-» и т. д. , т.е. Например, вот так: const dd=923874234; Также константы можно делать в секции процедур, - «procedure CycleProcesEvents;
    const dd=923874234;»

    Процедуры.
    Процедуры возможны без параметров, причём в процедуре должен быть один «Begin», как начало процедуры и один «end;», как конец процедуры. В разделе процедур, может быть раздел разметки меток, например: «Label CycleProcesEventsL, CycleProcesEvents_ret,DrawWindow,key,button,exit,My1;».
    В разделе процедур, в секции кода, могут быть использованы локальные метки «CycleProcesEventsL:», на которые можно переходить с помощью «goto», например «goto CycleProcesEventsL;» Процедура может быть определена как forward, например «procedure BEGINPROGRAM;forward;» и указана как стартовая, - «procedure BEGINPROGRAM;forward; {#START PROJECT DAK}» (см. директивы) или «procedure BEGINPROGRAM; {#START PROJECT DAK}» (см. директивы). Указание процедуры стартовой {#START PROJECT DAK}, должно быть после её имени до «end;» процедуры.

    Процедура. Секция кода.
    Секция кода может быть только в процедуре, но не в модуле.
    procedure CycleProcesEvents;
    Begin
    {Секция кода процедуры}
    end;
    В секции кода:
    RET; — аналог ассемблеровского RET, т. е. возврат из процедуры
    INT0x40; - аналог ассемблеровского INT 0x40,
    HALT; – немедленное завершениие программы
    GOTO; - переход на метку внути процедуры.
    IF … - условый переход.

    Неиспользуемые процедуры не компилируются!

    Условный переход IF.
    Условный переход IF, должен содержать регистр-идентификатор, одно из условий сравнения ( "=" ">=" "=>" "<=" "=<" "<>" "><" "<" ">" ) и числовой идентификатор, а далее «then goto» и МЕТКА. Обработка других вариаций, пока не написана. Например: «If EAX=1 then goto DrawWindow;», «If AX=1 then goto DrawWindow;», «If AL=1 then goto DrawWindow;», «If AH=1 then goto DrawWindow;»

    Присваивание.
    Допустимо присваивание только 32-разрядным регистрам EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI. Им можно присваивать числовые значения, а также регистры {8 битные регистры процессора} AL, BL, CL, DL, AH, BH, CH, DH, {16 битные регистры процессора} AX, CX, DX, BX, SP, BP, SI, DI, {32 битные регистры процессора} EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI.

    Никаких логических или арифметических операций, пока не реализовано.

    При написании и испытаниях DAKа использовалась среда Borland Delphi 7.
    Проверялись и испытывались примеры на диске C:\ (т.е. в папке C:\DAKproject\ )

    Ну вот на этом пока всё.
    Автор будет совершенствовать DAK дальше. Вот только не знаю за что “хваться” в первую очередь. :-) Жду комментариев.
  • Порядок работы с DAK в простом изложении:
    DAK «привязан» к файлу uMain.pas , оба файла должны обязательно находится в одном каталоге.

    При использовании среды Delphi, для написания программы необходимо: Открыть Project.dpr, открыть файл uMain.pas который используется Project.dpr, отредактировать uMain.pas, НЕ ЗАБЫТЬ СОХРАНИТЬ и запустить из среды Delphi (кл. F9), в случае успешной компиляции, будут созданы файлы Project.prt и Main.asm, далее согласно установленных директив '{#START CompileProject.bat}' и '{#START RunProject.bat}' в файле uMain.pas, проект будет скомпилирован FASM.EXE и запущен в KlbrInWin.

    При использовании без среды Delphi, но с проверкой синтаксиса через dcc32, для написания программы необходимо: открыть текстовым редактором uMain.pas отредактировать его, СОХРАНИТЬ и запустить DAK.bat, далее DAKом будет запущена предварительная проверка синтаксиса (dcc32CheckProject.bat), потом обработка самим DAKом , в случае успешной компиляции, будут созданы файлы Project.prt и Main.asm, далее согласно установленных директив '{#START CompileProject.bat}' и '{#START RunProject.bat}' в файле uMain.pas, проект будет скомпилирован FASM.EXE и запущен в KlbrInWin.

    При использовании без среды Delphi и без проверки синтаксиса через dcc32, для написания программы необходимо: открыть текстовым редактором uMain.pas отредактировать его, СОХРАНИТЬ и запустить DAKDelphi.bat (либо 'DAK.exe /delphi' из коммандной строки), далее обработка самим DAKом , в случае успешной компиляции, будут созданы файлы Project.prt и Main.asm, далее согласно установленных директив '{#START CompileProject.bat}' и '{#START RunProject.bat}' в файле uMain.pas, проект будет скомпилирован FASM.EXE и запущен в KlbrInWin.
  • Была такая близкая этому топику тема на местном форуме.
    Ещё раз о HiAsm про Hiasm для Kolibri
    но, быстро вникнуть не получилось и забросилось.
  • компилятор, который сможет компилировать файлы с мнемоникой Pascal
    Компилятор Oberon-07 имеет очень похожий синтаксис и работает в самой Колибри viewtopic.php?f=33&t=2443
    Там на скриншоте под спойлером видно кусочек кода для KolibriOS viewtopic.php?f=33&t=2443#p52763

    Судя по приведённому примеру кода, это больше похоже на высокоуровневый ассемблер, чем на паскаль.
    Если именно это необходимо, то можно этого добиться с помощью ассемблерных макросов.
    Или вот, например, можно использовать HJWasm(форк JWasm(форк Open Watcom Assembler)), который поддерживает многие HighLevel конструкции "из коробки".
    Пример кода для Колибри под спойлером viewtopic.php?f=2&t=2586&p=65582#p55776
    Или вот ещё пример кода из демки Masm2Htm.asm(раньше было на сайте у Japheth). Я пропускаю здесь не очень интересные места, заменяя закомментированными точками:
    Spoiler:

    Code: Select all

        .if ( eax == 0 )
    ;......................
        .endif
        
        .while ( byte ptr [esi] )
    ;......................
        .endw
        
    .while (ecx)
    ;......................
        .if ( incomment == 0 && inquotes == 0 && inangles == 0 )
            .if ( startword == 0 )
    ;......................
                .if ( edi > startline )
    ;......................
                .endif
    
            .if ( al == '<' )
    ;......................
            .elseif ( al == '>' )
    ;......................
            .elseif ( al == '&' )
    ;......................
            .else
                .if ( incomment && ( al == cr || al == lf ))
    ;......................
                    .while ( byte ptr [esi] )
    ;......................
                    .endw
    ;......................
                .endif
    ;......................
            .endif
    
    И, похоже, что теперь также поддерживается ".SWITCH - .CASE - .DEFAULT - .ENDSWITCH" http://masm32.com/board/index.php?topic=5280.0
    Оно, кстати, и под Колибри должно работать(я выкладывал давно уже в чате скриншот работы Masm2Htm.kex).
    Конкретно в этом чате chatlogs/chatlog2014-04-23.html
    0CodErr « Wed Apr 23, 2014 11:36 am » собрал вон ту штуку http://japheth.de/JWasm/masm2htm.html под KolibriOS можно полученный из исходника html открыть в WebView:
    Spoiler:Image
    Также тут кто-то уже предлагал Язык ассемблера с упрощенным синтаксисом viewtopic.php?f=4&t=2645

    Что касается именно самого Delphi, то это можно сделать, например, с помощью Delphi2.0(это всё равно лучше самопального транслятора).
    Я как-то уже спрашивал, нужен ли кому-то пример. Сказали, что не нужен.
    Вот в этом чате сказали chatlogs/chatlog2013-04-05.html
    Spoiler:
    0CodErr « Fri Apr 05, 2013 5:06 pm » я могу сделать для Delphi 2.0 пример, похожий на примеры для FreeBasic и XDS
    ; ...............................................................
    Mario_r4 « Fri Apr 05, 2013 9:10 pm » Дельфи не нужен же! ;-)
    Mario_r4 « Fri Apr 05, 2013 9:10 pm » Совсем не нужен.
    А вообще исходник такой:
    Spoiler:

    Code: Select all

    unit test;
    (* -------------------------------------------------------- *)
    interface
    (* -------------------------------------------------------- *)
    Type
      SIZE = Record height, width : Word end;
    (* -------------------------------------------------------- *)
    Const
     (* WinDow styles *)
      WS_SKINNED_FIXED    =  $4000000;
      WS_SKINNED_SIZABLE  =  $3000000;
      WS_FIXED            =  $0000000;
      WS_SIZABLE          =  $2000000;
      WS_FILL_TRANSPARENT = $40000000;
      WS_FILL_GRADIENT    = $80000000;
      WS_COORD_CLIENT     = $20000000;
      WS_CAPTION          = $10000000;
    
     (* Caption styles *)
      CAPTION_MOVABLE     = $00000000;
      CAPTION_NONMOVABLE  = $01000000;
    
     (* Events *)
      REDRAW_EVENT        = 1;
      KEY_EVENT           = 2;
      BUTTON_EVENT        = 3;
    
     (* Colors *)
      COLOR_BLUE          = $000000FF;
      COLOR_RED           = $00FF0000;
      COLOR_GREEN         = $0000FF00;
      COLOR_WHITE         = $00FFFFFF;
      COLOR_BLACK         = $00000000;
    
      sz_hello  = AnsiString('Hello, Delphi 2.0!');
    (* -------------------------------------------------------- *)
    Var
      Left, Top, Width, Height : cardinal;
      Scr : SIZE;
    (* -------------------------------------------------------- *)
    procedure Main; forward;
    procedure RedrawStart; assembler; forward;
    procedure RedrawFinish; assembler; forward;
    procedure DrawWinDow(Left, Top, Width, Height: cardinal; Caption: PChar; BackColor, Style, CapStyle: cardinal); StdCall; assembler; forward;
    procedure ThreadTerminate; assembler; forward;
    procedure On_Redraw;  StdCall; forward;
    procedure On_Key;  StdCall; forward;
    procedure On_Button;  StdCall; forward;
    function  WaitEvent : cardinal; assembler; forward;
    function  GetKey : cardinal; assembler; forward;
    function  GetButton : cardinal; assembler; forward;
    function  GetScreenSize : SIZE; assembler; forward;
    (* -------------------------------------------------------- *)
    implementation
    (* -------------------------------------------------------- *)
    procedure Main();
    begin
      Scr := GetScreenSize();
    
      Width  := Scr.width  Shr 2;
      Height := Scr.height Shr 2;
      Left   := (Scr.width  - Width)  Shr 1;
      Top    := (Scr.height - Height) Shr 1;
    
      While TRUE Do begin
        Case WaitEvent() Of
        REDRAW_EVENT : On_Redraw;
        KEY_EVENT    : On_Key;
        BUTTON_EVENT : On_Button;
        end;
      end;
    end;
    (* -------------------------------------------------------- *)
    procedure On_Redraw();
    begin
     RedrawStart;
     DrawWinDow(Left, Top, Width, Height, sz_hello, COLOR_WHITE, WS_SKINNED_FIXED + WS_COORD_CLIENT + WS_CAPTION, CAPTION_MOVABLE);
     RedrawFinish;
    end;
    (* -------------------------------------------------------- *)
    procedure On_Key();
    begin
      GetKey;
    end;
    (* -------------------------------------------------------- *)
    procedure On_Button();
    begin
      Case GetButton() Shr 8 Of
      1 : ThreadTerminate;
      end;
    end;
    (* -------------------------------------------------------- *)
    procedure RedrawStart();
    Asm
            push   ebx
            mov    eax, 12
            mov    ebx, 1
            int    64
            pop    ebx
    end;
    (* -------------------------------------------------------- *)
    procedure RedrawFinish();
    Asm
            push   ebx
            mov    eax, 12
            mov    ebx, 2
            int    64
            pop    ebx
    end;
    (* -------------------------------------------------------- *)
    procedure DrawWinDow(Left, Top, Width, Height : cardinal; Caption : PChar; BackColor, Style, CapStyle: cardinal);
    Asm
            push   ebx
            push   edi
            push   esi
            xor    eax, eax
            mov    ebx, [Left]
            shl    ebx, 16
            add    ebx, [Width]
            mov    ecx, [Top]
            shl    ecx, 16
            add    ecx, [Height]
            mov    edx, [Style]
            or     edx, [BackColor]
            mov    edi, [Caption]
            mov    esi, [CapStyle]
            int    64
            pop    esi
            pop    edi
            pop    ebx
    end;
    (* -------------------------------------------------------- *)
    function WaitEvent(): cardinal;
    Asm
            mov    eax, 10
            int    64
    end;
    (* -------------------------------------------------------- *)
    function GetKey(): cardinal;
    Asm
            mov    eax, 2
            int    64
    end;
    (* -------------------------------------------------------- *)
    function GetButton(): cardinal;
    Asm
            mov    eax, 17
            int    64
    end;
    (* -------------------------------------------------------- *)
    procedure ThreadTerminate();
    Asm
            mov    eax, $FFFFFFFF;
            int    64
    end;
    (* -------------------------------------------------------- *)
    function GetScreenSize(): SIZE;
    Asm
            push   ebx
            mov    eax, 61
            mov    ebx, 1
            int    64
            pop    ebx
    end;
    (* -------------------------------------------------------- *)
    end.
    
    LScript.x:
    Spoiler:

    Code: Select all

    PATH_SIZE    =  1024;
    PARAMS_SIZE  =   256;
    STACK_SIZE   =   256;
    
    SECTIONS
    {
    
      .text  : AT(0) {
        code = .;
    
            LONG(0x554e454D);
            LONG(0x31305445);
            LONG(1);
            LONG(start);
            LONG(end);
            LONG(end + PATH_SIZE + PARAMS_SIZE + STACK_SIZE);
            LONG(end + PATH_SIZE + PARAMS_SIZE + STACK_SIZE);
            LONG(end + PATH_SIZE);
            LONG(end);
    
    		start = .;
    		
        *(.text)
    
      }
    	
      .data : AT(data - code) {data = .; *(.data)}
    	
      .bss  : AT(bss - code)  {bss = .;  *(.bss)}
    	
      end = .;
    }
    Так я его собирал:
    Spoiler:

    Code: Select all

    Set Name=test
    dcc32 -J %Name%.pas
    editbin %Name%.obj
    ld -T LScript.x %Name%.obj -o %Name%.kex
    objcopy -O binary -j .text -j .data -j .bss %Name%.kex
    А вот скриншот запущенного приложения из Колибри:
    Spoiler:Image
    Скомпилированный бинарник: