C--. Первое знакомство

0d6194f4bd54441b85acce5e6696e434.PNG Процесс портирования и создания средств разработки программ для KolibriOS продолжается. По наиболее активно используемым языкам программирования мы публикуем статьи. Сегодня мы начинаем рассказывать о языке С--, вокруг которого сложилось активное сообщество в 2000-е годы. Подробности под катом.


Кратко о языке с официального сайта:


C-- — это язык программирования, занимающий промежуточное положение между ассемблером и Cи. Идеально подходит для написания маленьких программ, резидентов (TSR), драйверов, обработчиков прерываний. Для работы с языком C-- необходимо знакомство с ассемблером и Cи. Сейчас С-- умеет генерировать 32-битный код под ДОС и Windows (прим. ред., а также под MenuetOS, KolibriOS).

Автором языка SPHINX C-- является Peter Cellik (CANADA). Последняя авторская версия SPHINX C-- v0.203 от 28.Oct.96. К сожалению автор отказался от дальнейшего развития языка. Сам язык вместе с исходные текстами был объявлен сиротой и отдан никому в никуда. Т.е. делайте что хотите. А почему бы и не сделать? На этой страничке Вы найдете самую последнюю (но уже не авторскую) версию самого языка, библиотеки, примеры программ, описание самого языка и библиотек в формате Notron Guide и много другой полезной информации по языку C--.


После Питера Селлика поддержкой занимался Михаил Шекер, но он прекратил разработку несколько лет назад. В прошлом году исходники были выложены на Github https://github.com/jossk/c--sphinx, но мы узнали об этом только в марте 2016 года.


Было решено рассказать о данном языке по двум причинам:


  1. На нём написаны несколько популярных программ KolibriOS, среди которых и Eolite — пожалуй, самый используемый файловый менеджер.
    287cd20dbf094c84a439233f8635e605.png
  2. Относительно недавно компилятор данного языка был портирован для KolibriOS (ответ на вопрос о лицензии можно найти тут).

Немного о процессе портирования от GerdtR:


Итак. Сначала я переделал код под gcc. Исходники просто были написаны для Watcom C, ну и пусть не значительная, но несовместимость была. Исправил пару названий переменных (extern в ваткоме можно, видимо), и обозначение 64 битных чисел по другому. Потом уже Leency выявил, что gcc-версия совсем не ищет файлы в текущей папке, только в папке с самим экзешником. Когда и это исправил осталось самое сложное: порт для Колибри. Ну так как под С я в КОС не писал, то была стандартная проблема — с кем линковать, да и какие инклудники брать. Выбор не широкий, menuetlibc отпал сразу, как я, покопавшись в исходниках, увидел ещё старые функции обращения к файлам (ф56 вроде). Короче menuetlibc устарел сильно, остался newlib. Долго разбирался, как всё таки на выходе получить kex, а не PE, помог один Makefile, где писалась дополнительно обработка objcopy. Ну, а дальше уже дописывание функций, которых нет в newlib (например stat не было, в port.c лежит его реализация). Ну и пара функций преобразования кодировок ANSI→ASCII, а точнее заглушек, потому как русских букв всё равно в строках компилятора нет. Ну и последней проблемой было, да и частично осталось вот это: из-за newlib (скорее всего, больше некому) текущий каталог устанавливается как путь до самого сmm (а обычно /rd/1), потому оказывается, что узнать, где лежит исходник компилятор не может, хоть откуда его запускай. Выход на данный момент — копировать компилятор в папку с исходниками, либо указывать абсолютный путь. Кстати, раньше символ '/' считался началом параметра и абсолютный путь указать было не возможно, сейчас можно. Но с абсолютным путём пока не уверен, что инклудники находить будет. Пока что-то не хочется с этим возиться, да и можно просто написать -IP=»/hd1/1/my_source». В теории должно работать, на практике никто не спрашивал. Кстати… указать в форуме что ли, что параметры через '-' указывать теперь… И при запуске без параметров, в той таблице поправить, а то некоторая путаница получается. Ладно, потом как-нибудь. Ну вот в общем, вся история. Самое сложное было — это разобраться, откуда брать либы :) Сам код довольно несложный, не в супер порядке, но особо ковыряться в коде не пришлось

Руководство по языку находится по ссылке http://www.c--sphinx.narod.ru/c--doc.htm. Рассмотрим пример простого приложения для KolibriOS:


#define MEMSIZE 4096*10

#include "../lib/io.h"
#include "../lib/gui.h"

void main()
{
        word id;
        dword file;
        io.dir.load(0,DIR_ONLYREAL);
        loop() switch(WaitEvent())
        {
                case evButton:
                        id=GetButtonID();              
                        if (id==1) ExitProcess();
                        break;

                case evKey:
                        GetKeys();
                        if (key_scancode == SCAN_CODE_ESC ) ExitProcess();
                        break;

                case evReDraw:
                        draw_window();
                        break;
        }
}
void draw_window()
{
        proc_info Form;
        int i;
        DefineAndDrawWindow(215,100,350,300,0x34,0xFFFFFF,"Window header");
        GetProcessInfo(#Form, SelfInfo);
        for (i=0; i

9cf2cfdafc5542bda01b435bf3a41f7a.jpg

Как видите, данный код почти не отличается от кода на Си, но при этом есть возможность писать спокойно в почти ассемблерном стиле, аналогично написанию оберток для системных функций. Например, функция создания окна:


void DefineAndDrawWindow(dword x, y, size_w, size_h, byte WindowType,dword WindowAreaColor, EDI, ESI)
{
    EAX = 12;              
    EBX = 1;
    $int 0x40

    $xor EAX,EAX
    EBX = x << 16 + size_w;
    ECX = y << 16 + size_h;

    EDX = WindowType << 24 | WindowAreaColor;
    $int 0x40

    EAX = 12;              
    EBX = 2;
    $int 0x40
}

Чем же он привлекателен для разработчиков ПО для KolibriOS? Во-первых тем, что начать писать на нём очень легко. Это был единственный язык, не считая FASM, на котором можно было просто начать писать, не заморачиваясь с настройкой кросс-компиляции (сейчас в этом деле Си уже набирает обороты). Во-вторых, для C-- было написано множество библиотек и различных оберток над системными функциями. Среди них собственный набор элементов интерфейса и даже неплохие шрифты:


53453681c3de47a0a7c7601ff4124258.png


Вы наверняка зададитесь вопросом: если всё так прекрасно, то в чем же проблема? Почему он не применяется повсеместно, хотя бы в рамках проекта KolibriOS?
Ответ следующий. Несмотря на преимущество в простоте освоения, при его использовании всплывают и недостатки:


  • плохая оптимизация результирующего кода;
  • практически отсутствуют приоритеты операций (C-- всё считает слева направо, т.е. 2+2×2=8, а не 6);
  • самое главное, хоть он и похож на Си, но это другой язык программирования со своей сферой применения. В рамках KolibriOS он наиболее подходит для создания программ с графическим интерфейсом и почти не применяется в системном программировании.

Комментарии (1)

  • 20 июля 2016 в 16:44 (комментарий был изменён)

    0

    Будучи школьником изучающим ассемблер наткнулся на этот C--. Но тогда уже существовал MASM32, обладающий директивами и макросами в стиле proto/invoke, .if/.else и т.п., превращающими его в «почти си», а потом и FASM появился, на базе макросов которого вообще можно DSL написать, так интерес к C-- и сошёл на нет. Не зря бросают C--, он мертворожденный, IMHO.

© Habrahabr.ru