Files
Sprinter-SDCC/third_party/solid-c/DOC/DEVEL-2.RUS
T
snark13 c71e249a4e Add full compiler toolchain, libc, examples and reference docs
First substantive commit: the entire Sprinter C compiler tree on top of
the bare README+gitignore initial commit.

What's in here:
  bin/sprinter-cc        — driver script invoking SDCC + linker + mkexe
  libc/                  — Sprinter-specific libc layer over ESTEX/BIOS
                           (conio, gfx, io, mem, stdio + headers)
  runtime/               — crt0 variants (default/small/banked/minimal)
                           + heap + bank trampolines
  toolchain/             — mkexe (SprintEXE packer, C + tests)
  examples/              — 30 demo programs (gfx, file I/O, env, time, …)
  lib/Makefile           — builds the libc archive (sprinter.lib)
  docs/                  — converted Sprinter manuals + asm reference samples
  third_party/           — solid-c reference compiler dump + sdcc setup script
  release_docs/          — packaging / release notes

gitignore overhaul:
  • Drop dangerous blanket patterns: *.asm (would hide docs/samples/*.asm)
    and *.exe (case-insensitive match was hiding third_party/solid-c/*.EXE
    on macOS APFS).  Replaced with examples/*/*.{asm,exe,…} and lib/*.lib.
  • Restore tracking of toolchain/mkexe/tests/{one,big}.bin — those are
    INPUT fixtures, not build outputs.
  • Collapse the duplicated SDCC/C/Sdcc sections into one section per
    concern (build outputs / vendored / OS-junk).
  • Add .sprinter-cc-*/, build/ (catches lib/build/ too), .claude/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 16:13:21 +03:00

229 lines
9.4 KiB
Plaintext

СОЗДАНИЕ БИБЛИОТЕК
Известны два способа создания библиотеки. Оба они будут описаны в следующих
параграфах. Первый из них, метод "а" - быстрый и легкий по исполнению, однако
к собираемым пользовательским программам прилинковываются в том числе и такие
функции, которые не обязательно будут использоваться.
В отличие от первого, способ "b" реализуется сложнее и требует большего вре-
мени, но получаемые в соответствии с ним пользовательские программы будут со-
держать в себе только те функции, которые заведомо применяются в программе.
Стандартная библиотека компилятора "clib.irl" создается именно по способу "b".
1. Простой способ создания библиотеки
Рассмотрим пример двух функций "power" и "log2":
int power(x,e)
int x,e;
{
int y;
for(y=1; e>0; e--)
y *= x;
return(y);
}
int log2(x)
int x;
{
int y;
for(y=0; x>1; x>>=1)
y++;
return(y);
}
Если эти функции помещаются в файл с именем XLIB.C, последовательность
создания библиотеки выглядит следующим образом:
cc1 xlib
cc2 xlib
as xlib
При выполнении этой последовательности будет создана библиотека с именем
XLIB.REL. Ниже приведена команда сборки программы, которая вызывает функции
из этой библиотеки:
ld prog,xlib,clib/l/gXMAIN
В этом случае нет необходимости писать ключ /l после имени библиотеки XLIB,
т.к. даже если его написать, тем не менее все функции, входящие в библиотеку
XLIB, будут скомпонованы с программой "prog".
Здесь будет описан способ включения в библиотеку программ, написанных на
Ассемблере. В качестве примеров взяты функции hex, ror и rol, помещенные в
файл ALIB.ASM:
public hex_, ror_, rol_
cseg
hex_: ; convert 0..F -> '0'..'F'
and 0Fh
add a,90h
daa
adc a,40h
daa
ret
ror_: ; ror(c,n) n bit rotate right char
inc e
rorl: dec e
ret z
rrca
jp rorl
rol_: ; rol(c,n) n bit rotate left char
inc e
roll: dec e
ret z
rlca
jp roll
Включение этих функций в библиотеку производится путем выполнения следующей
команды:
as alib.asm
Следующая команда вызывает линковку программы, как и в случае Си-программы:
ld prog,alib,clib/l/gXMAIN
Как видно из приведенных выше примеров, самый простой способ формирования
библиотеки - включение в нее тех программ, из которых компонуется программа.
Однако этот способ не совершенен, так как вызывает подключение всей библиотеки.
В следующем параграфе будет описан способ создания библиотеки, при котором
программа компонуется только из тех функций, к которым предполагаются обраще-
ния.
2. Создание полной библиотеки
2.1. Включение Си-программ в библиотеку
Здесь будет приведен тот же пример, что и выше - включение файла XLIB.C,
содержащего тексты функций POWER и LOG2 в библиотеку.
Вначале нужно "разделить" файл XLIB.C на составляющие его функции, записав
их в отдельные файлы POWER.C и LOG2.C. Далее необходимо выполнить следующие
команды:
cc1 power
cc1 log2
cc2 power
cc2 log2
as power
as log2
ol a xlib.irl power log2
При выполнении этой последовательности команд, происходит следующее:
1. Си-тексты функций транслируются в ассемблерные листинги.
2. В результате ассемблирования получаем модули с расширением ".rel".
3. С помощью библиотекаря OL из двух модулей с расширением ".rel"
создается библиотека XLIB.IRL.
После создания библиотеки XLIB.IRL, файлы POWER.REL и LOG2.REL уже не нужны
и их можно удалить.
Применение библиотеки XLIB.IRL определяется следующей командой:
ld prog,xlib/l,clib/l/gXMAIN
После имени библиотеки XLIB нужен ключ /l как указание линкеру подключить
к программе только необходимые ей функции.
При сборке программ, состоящих из большого числа файлов (функций), имеет
значение порядок расположения функций. Ниже приведены два примера: один из
них правильный, а другой неправильный.
Правильный пример:
char islower(c)
char c;
{
return('a'<=c && c<='z');
}
char toupper(c)
char c;
{
return(islower(c) ? c-'a'-'A' : c);
}
В данном примере в библиотеку включается файл X.C, состоящий из двух
функций. В этом случае функция "islower" расположена в файле X.REL перед
функцией "toupper". Поэтому при редактировании связей по ключу /l линкер
не выдаст диагностику об ошибке типа отсутствия определения.
Но если написать вначале текст функции "toupper", возникает следующий
неправильный пример:
char toupper(c)
char c;
{
char islower();
return(islower(c) ? c-'a'-'A' : c);
}
char islower(c)
char c;
{
return('a'<=c && c<='z');
}
В результате расположение модулей в библиотечном файле будет неправильным.
Подводя итоги сказанному, можно резюмировать, что для правильного порядка
расположения модулей в библиотеке нужно в исходной программе вначале писать
вызываемую функцию, а после нее - вызывающую.
2.2. Создание библиотеки модулей на Ассемблере
По сравнению с описанием включения в библиотеку, которое было дано в п.1,
здесь, файл ALIB.ASM следует предварительно разделить на следующие три файла
"hex.asm", "ror.asm" и "rol.asm":
HEX.ASM:
cseg
hex_:: and 0Fh
add a,90h
daa
adc a,40h
daa
ret
ROR.ASM:
cseg
ror_:: inc e
rorl: dec e
ret z
rrca
jp rorl
ROL.ASM:
cseg
rol_:: inc e
roll: dec e
ret z
rlca
jp roll
После того, как каждый из них будет ассемблирован и получен файл с расши-
рением ".rel", вызывается библиотекарь OL для создания библиотеки:
as hex
as ror
as rol
ol a alib.irl hex ror rol
Применение библиотеки ALIB.IRL определяется следующей командой:
ld prog,alib/l,clib/l/gXMAIN
При сборке программы, точно таким же образом, как и для сборки Си-программы
из модулей, должна соблюдаться последовательность записи исходного текста, а
именно: вызываемая функция должна быть записана прежде, а вызывающая ее, вслед
за ней.