diff options
| author | kx <kx@radix-linux.su> | 2026-10-09 18:00:15 +0300 |
|---|---|---|
| committer | kx <kx@radix-linux.su> | 2026-10-09 18:00:15 +0300 |
| commit | 065da3509019b15dd0e678072e6be629e5330bef (patch) | |
| tree | 69c934c9e786ac048b4fbe8f4c4c5571661521f4 /doc/src/libmcpu-architecture-runtime-ru.tex | |
| parent | d130fe27fa753be02ed76fd9b277aa3c3d928eb9 (diff) | |
| download | libmcpu-0.4.0.tar.xz | |
Version 0.4.00.4.0
Diffstat (limited to 'doc/src/libmcpu-architecture-runtime-ru.tex')
| -rw-r--r-- | doc/src/libmcpu-architecture-runtime-ru.tex | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/doc/src/libmcpu-architecture-runtime-ru.tex b/doc/src/libmcpu-architecture-runtime-ru.tex new file mode 100644 index 0000000..2ecf4cb --- /dev/null +++ b/doc/src/libmcpu-architecture-runtime-ru.tex @@ -0,0 +1,349 @@ +\section{Host backing memory spaces и loader} +Host allocation не является частью PTR64. Активные architectural memory spaces имеют независимый anonymous mmap() backing; guest pointer содержит selector+offset и никогда не содержит host virtual address. + +\subsection{Anonymous mmap only} +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + mmap(NULL, capacity, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0) +\end{lstlisting} + +PROGRAM, DATA, STACK, CONTROL, INPUT, OUTPUT, TRACE и HEAP получают отдельные mappings. Loader читает image bytes обычным read() в anonymous memory. PROGRAM после загрузки переводится host-side в read-only mapping; guest access policy дополнительно проверяется instruction resolver. CONTROL/INPUT сохраняются host-writable, потому что runtime должен иметь возможность менять configuration/input между фазами исполнения, но guest STOREP в них запрещён. + +\subsection{Architectural size, capacity и HEAP limit} +\begin{center} +\begin{tabularx}{0.92\textwidth}{@{}L{34mm}Y@{}} +\toprule +\textbf{Величина} & \textbf{Смысл}\\ +\midrule +\code{segment.size} & точное число байтов, доступных guest-программе\\ +\code{segment.capacity} & округлённый по страницам размер host mapping\\ +\code{heap.size} & текущий guest-visible размер HEAP\\ +\code{heap.capacity} & текущая вместимость host backing HEAP\\ +\code{heap.limit} & настроенный неизменяемый максимальный размер HEAP\\ +\bottomrule +\end{tabularx} +\end{center} + +Все CPU bounds checks используют architectural size, а не host capacity. HEAP additionally reserves offsets 0..15; первый ordinary heap byte имеет offset CPU\_HEAP\_BEGIN = 16. + +Relocatable host backing. PTR64(HEAP,offset) не зависит от host base. Поэтому будущая реализация heap growth может создать larger anonymous mapping, скопировать bytes и заменить host base, не меняя ни одного guest pointer. + +\subsection{MELF loader и окончательный process image} +Начиная с MELF ABI, development sidecar images не являются форматом запуска. \code{mcpu-ld} создаёт ET_EXEC/ET_DYN с segment metadata, а \code{mcpu-run} валидирует target description, program-model metadata, program headers и relocation records до передачи управления guest. Для ABI v2 все preload-модули сначала полностью читаются и валидируются, затем назначаются независимые PROGRAM/DATA bases, после чего применяются retained relocations. PROGRAM после relocation phase переводится в read-only host mapping. + +\section{Fault, atomicity и invariants} +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + • REG24 проверяет width, natural alignment и границы register file. + • JMPP/CALLP требуют PROGRAM PTR64: NULL, другой SEG или offset вне program.size дают + POINTER_FAULT до изменения PC/SP/STACK. + • CALLP сначала валидирует target и stack space; return PC записывается только после + успешной полной проверки. + • All-zero PTR64 является NULL и даёт POINTER_FAULT при indirect dereference. + • Assembler резервирует DATA[0..15]; ordinary DATA labels начинаются не раньше 0x10. + • CODE64 target должен ссылаться внутрь PROGRAM. + • STACK operations сначала проверяют bounds, затем меняют SP/FP/memory. + • PUSHFP проверяет место и корректность текущего FP до записи. + • POPFP сначала читает saved value и проверяет saved_fp <= stack_size; при fault ни FP, + ни SP не меняются. + • SETFP требует allocated STACK и корректный SP. + • RESTSP требует FP <= stack_size. + • LDFP/STFP/LEAFP используют signed OFF64 относительно FP и выполняют bounds + checking. + • SETSP принимает только STACK PTR64; wrong segment -> pointer fault, out-of-range offset + -> stack fault. + • Ни одна FP/SP management instruction не меняет PSW. + • CALL/CALLP/RET сами PSW-neutral; normal-function ABI считает PSW[15:0] volatile, TF/IF/ + MODE persistent control state, HF отдельным execution state. + • PADD/PADDI/PSUB/PSUBI проверяют 60-bit PTR64 offset, но не object lifetime. + + + + • BMOV/BMOVI сначала проверяют complete source и destination ranges; при fault destination + memory не изменяется. Overlap разрешён и имеет memmove semantics. + • CPU не обеспечивает ownership текущего frame: правило SP <= FP внутри FP-frame и + stack-scope discipline обеспечиваются compiler/ABI. +\end{lstlisting} + +Нельзя хранить долгоживущий указатель на automatic object после release scope/frame. PTR64 остаётся битово корректным, но high-level program нарушает lifetime. Это семантическая ошибка compiler/program, а не PTR64 encoding fault. + +\section{Byte order и architectural object representation} +LibMCPU намеренно разделяет два независимых byte-order domain. Это один из фундаментальных ABI contracts: PROGRAM является переносимым сериализованным instruction stream, а register file и memory segments содержат runtime objects в target representation, совместимом с LibMPU. + +\begin{figure}[ht] +\centering +\begin{tikzpicture}[font=\sffamily\small,>=Latex,node distance=12mm and 15mm] + \node[draw=McpuBlue,very thick,rounded corners,fill=McpuBlueBg,minimum width=72mm,minimum height=22mm,align=center] (prog) + {\textbf{PROGRAM / machine fields}\\[-1mm]\scriptsize OPCODE16, REG24, IMM64, ADDR64, CODE64, OFF64\\\textbf{канонический MSB-first}}; + \node[draw=McpuGreen,very thick,rounded corners,fill=McpuGreenBg,right=of prog,minimum width=72mm,minimum height=22mm,align=center] (data) + {\textbf{Архитектурные объекты данных}\\[-1mm]\scriptsize register file, DATA, STACK, CONTROL, INPUT, OUTPUT, TRACE, HEAP\\\textbf{target representation LibMPU}}; + \draw[->,thick,McpuBlue2] (prog) -- node[above]{decode / execute} (data); + \node[below=11mm of prog,align=center,font=\ttfamily\small] (pb) {0x1122334455667788\\11 22 33 44 55 66 77 88}; + \node[below=11mm of data,align=center,font=\ttfamily\small] (db) {тот же u64 на текущем LE target\\88 77 66 55 44 33 22 11}; + \draw[->,McpuBlue] (prog.south) -- (pb.north); + \draw[->,McpuGreen] (data.south) -- (db.north); +\end{tikzpicture} +\caption{Сериализация PROGRAM и целевое представление объектов данных являются разными byte-order domains.} +\end{figure} + +\subsection{PROGRAM: canonical MSB-first} +Все multi-byte machine fields внутри PROGRAM кодируются старшим байтом вперёд. Это правило не зависит от host CPU, LibMPU byte order или будущего object-file container. + +value = 0x1122334455667788 + +IMM64 / CODE64 / ADDR64 / OFF64 bytes: 11 22 33 44 55 66 77 88 + +REG24 также является canonical machine field: его три байта формируются из WIDTH и ADDRESS по уже определённому битовому layout. Decoder не делает C-cast на packed host structure. + +\subsection{Data-object domain} +Register file, DATA, STACK, CONTROL, INPUT, OUTPUT, TRACE и HEAP используют одно target object representation. Для integer-like objects byte order берётся из target profile LibMCPU, который совпадает с configured LibMPU: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + CPU_DATA_BYTE_ORDER = MPU_BYTE_ORDER + CPU_DATA_WORD_ORDER = MPU_WORD_ORDER + CPU_DATA_BYTE_ORDER_* = corresponding LibMPU settings + CPU_DATA_WORD_ORDER_* = corresponding LibMPU settings +\end{lstlisting} + +На текущей little-endian конфигурации: + +u64 value 0x1122334455667788 address+0 88 address+1 77 address+2 66 address+3 55 address+4 44 address+5 33 address+6 22 address+7 11 + +Общее representation. Если один object скопирован между register file или любыми data-object spaces без числового преобразования, его bytes не переставляются. Endian conversion не является скрытым side effect memory instructions. + +\subsection{Явные helper families в реализации} +Чтобы source code executor/assembler визуально не смешивал два domain, используются две группы accessors: + +\_\_cpu\_code\_get\_u16 / \_\_cpu\_code\_put\_u16 \_\_cpu\_code\_get\_u32 / \_\_cpu\_code\_put\_u32 \_\_cpu\_code\_get\_u64 / \_\_cpu\_code\_put\_u64 + +\_\_cpu\_data\_get\_u16 / \_\_cpu\_data\_put\_u16 \_\_cpu\_data\_get\_u32 / \_\_cpu\_data\_put\_u32 \_\_cpu\_data\_get\_u64 / \_\_cpu\_data\_put\_u64 + +code-helpers явно собирают/разбирают MSB-first fields. data-helpers работают с target object representation через byte-safe copy semantics. Слово data здесь означает architectural data-object domain, а не только PTR64 segment DATA=0x0; эти helpers применимы также к register-file и STACK bytes. + +Именно поэтому выбрано имя \_\_cpu\_data\_get\_u*, а не \_\_cpu\_object\_get\_u*: в исходниках сразу виден контраст code vs data. Во избежание путаницы с segment DATA это значение термина закреплено в ABI documentation. + +\subsection{Integer, PTR64, return PC и overlapping registers} +Signed integer использует two's-complement; unsigned - binary modulo 2\textasciicircum{}N. Их физический byte/word order является target data profile. PTR64 логически остаётся 4-bit SEG + 60-bit OFFSET, но когда он находится в r64, DATA field, STACK argument или structure member, это обычный 64-bit data object. + +PTR64(PROGRAM, 0x1234) = 0x2000000000001234 + +current LE target bytes: 34 12 00 00 00 00 00 20 + +Return PC, который CALL/CALLP помещают в STACK, тоже является 64-bit STACK data object. В самой CALL instruction CODE64 target encoded MSB-first; pushed return PC хранится в target data representation. RET читает его как data object и устанавливает логический PC. + +Overlapping register views физически наблюдают одни и те же bytes. Поэтому endian-sensitive assembler code, который разбирает широкое integer value через меньшие overlapping views, является target-specific low-level code. Это допустимо и сознательно является частью ABI. + +\subsection{Real и Complex} +LibMCPU не вводит отдельный формат floating/complex objects поверх LibMPU. Для real<bits> применяется external object representation соответствующего LibMPU real type при текущем target profile. Для complex<bits> используется LibMPU complex representation двух real components половинной ширины. + +Complex physical half order не фиксируется независимым правилом LibMCPU. Он следует configured LibMPU word-order profile. Нельзя считать универсальной истиной, что первые bytes complex object всегда являются real component, а вторые - imaginary component. Complex arithmetic должен использовать C-opcodes/LibMPU representation либо явно target-specific byte code. + +\subsection{Assembler data directives} +Directive inside .data создаёт target data object либо явно заданную raw byte sequence, а не canonical machine field: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + .data + .align 8 +\end{lstlisting} + +x: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + .integer 64, 0x1122334455667788 +\end{lstlisting} + +text16: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + .ucs2 "Андрей" +\end{lstlisting} + +text8: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + .utf8 "Андрей" +\end{lstlisting} + +raw: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + .byte 0x11, 0x22, 0x33 + + .align 8 +\end{lstlisting} + +jump: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + .cptr target + + .text +\end{lstlisting} + +target: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + HALT +\end{lstlisting} + +На текущем LE target bytes объекта x идут как 88 77 66 55 44 33 22 11. Но literal того же значения в LDI находится в PROGRAM как canonical 11 22 33 44 55 66 77 88. .integer/.int, .real и .complex генерируют target/LibMPU object representation. .ucs2 пишет target-representation 16-bit code units, тогда как .utf8 и .byte являются raw byte sequences без endian conversion. .cptr генерирует target-representation PTR64(PROGRAM,label/ expression). + +.cptr является каноническим mnemonic directive. Исторический .codeptr принимается assembler как compatibility alias. .label не используется: запись name: уже определяет label, тогда как .cptr создаёт объект-указатель. Полные правила строк, .equ и expressions приведены в разделе 34. + +\subsection{Byte-preserving memory operations} +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + LOAD / STORE + LOADP / STOREP + PUSH / POP + LDSP / STSP + LDFP / STFP + BMOV / BMOVI +\end{lstlisting} + +Эти операции не знают endian semantics конкретного объекта. Они переносят physical bytes. В частности: + +DATA source --LOAD--> register A DATA source --BMOV--> DATA/STACK destination --LOAD--> register B + +bytes(register A) == bytes(register B) + +Точно так же structure/array/packed object может быть скопирован BMOV без type metadata и без byte swap. Padding bytes, если они являются частью complete object representation, тоже сохраняются. + +\subsection{Raw bytes, packed I/O и external byte order} +char, byte arrays, UTF-8 и arbitrary binary blobs являются последовательностями байтов и сами по себе endian не имеют. packed означает отсутствие layout padding, но не означает network/ big-endian или little-endian protocol representation. + +Если внешний файл/протокол требует конкретный byte order, assembler/program должен выполнить явное преобразование. Автоматическая endian conversion при LOAD/STORE запрещена этой ABI-моделью. Для явного разворота физического порядка байтов LibMCPU предоставляет универсальную инструкцию BSWAP, подробно определённую в разделе 32. Она не подменяет понятие external byte order: решение о необходимости swap принимает программа или инструмент. + +\subsection{Target metadata в MELF} +MELF уже содержит нормативную target metadata: byte order/container encoding, machine id и MCPU target description. Loader не пытается эвристически переконвертировать DATA/STACK-compatible objects при несовместимом profile. Образ либо совместим с текущей LibMPU target representation, либо отвергается до исполнения. PROGRAM machine fields при этом сохраняют отдельное canonical MSB-first кодирование. + +\subsection{Host alignment и unaligned accesses} +Byte order не меняет ранее принятые alignment rules. Guest memory остаётся byte-addressable; unaligned accesses разрешены ISA. Реализация не должна читать произвольную guest memory через alignment-sensitive или strict-aliasing-unsafe casts. \_\_cpu\_data\_get\_u*/put используют + +byte-safe copy semantics, а большие arbitrary objects перемещаются memcpy/memmove или LibMPU routines. + +\section{Pointer comparison, red zone, active/reserved} +PTR64 и BSWAP Этот раздел фиксирует четыре низкоуровневых соглашения CPU/assembler ABI, необходимые до появления object/executable format: сравнение PTR64, отсутствие stack red zone, поведение активных/зарезервированных segment selectors и универсальное преобразование порядка физических байтов. + +\subsection{Equality и ordering для PTR64} +PTR64 остаётся обычным 64-битным архитектурным значением. Для равенства/неравенства сравниваются все 64 бита: selector и 60-bit offset. Поэтому существующего integer compare достаточно: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + ICMP r64@p, r64@q + JZ equal + JNZ not_equal +\end{lstlisting} + +Это правило корректно и для разных selector: DATA:0x100 и STACK:0x100 не равны, поскольку их полные PTR64 различаются. Обычный ICMP может также выдавать signed integer flags для двух pointer bit patterns, однако ABI не придаёт этому результату смысла pointer ordering. + +Pointer ordering определяется только внутри одного segment selector и выполняется через PDIFF. Если selectors различны, PDIFF возвращает CPU\_EXEC\_POINTER\_FAULT и destination остаётся неизменным. + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + PDIFF r64@delta, r64@p, r64@q ; signed byte difference + ITEST r64@delta, r64@delta + JS p_less_than_q + JZ p_equal_q +\end{lstlisting} + +Разность двух 60-bit offsets всегда помещается в signed 64-bit диапазон. CPU не знает границ high-level объектов/массивов: same-segment ordering является низкоуровневой адресной операцией, а object-domain restrictions будущего языка остаются задачей compiler/program. + +\subsection{Stack red zone отсутствует} +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + CPU_ABI_STACK_RED_ZONE_SIZE = 0 +\end{lstlisting} + +STACK растёт вниз. Если текущий SP = X, байты ниже X не считаются принадлежащими функции как скрытая scratch-area. Функция должна сначала явно изменить SP через ADJSP или валидированный SETSP, а уже затем использовать выделенную область. + +Важно: ISA может физически позволить SP-relative address с отрицательным OFF64, если он попадает в allocated STACK. Это не превращает область ниже текущего SP в ABI red zone. Использование невыделенных bytes является ABI violation, а не обязательным аппаратным fault. + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + ; неправильно как normal ABI scratch + STSP -8, r64@tmp + + ; правильно + ADJSP -16 + STSP 0, r64@tmp + ... + ADJSP 16 +\end{lstlisting} + +Отсутствие red zone упрощает будущие traps/interrupts: обработчик может строить собственный frame ниже текущего SP, не уничтожая скрытые temporaries leaf-функции. + +\subsection{Active и reserved PTR64 selectors} +Selectors 0x0..0x7 имеют назначенную address-space semantics. Selectors 0x8..0xF остаются структурно допустимыми PTR64 values, но не имеют memory semantics. Это сохраняет возможность будущего расширения без изменения PTR64 encoding. + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + Операция над reserved PTR64 Правило +\end{lstlisting} + +(0x8..0xF) + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + MOV / SWAP / byte storage разрешено: bit pattern можно копировать и хранить + + ICMP equality / inequality разрешено как full 64-bit comparison + + PADD/PADDI/PSUB/PSUBI разрешено; selector сохраняется, arithmetic только по 60-bit + offset + + PDIFF разрешено только при одинаковом selector + + LOADP / STOREP / BMOV / BMOVI CPU_EXEC_POINTER_FAULT + + JMPP / CALLP CPU_EXEC_POINTER_FAULT + + SETSP CPU_EXEC_POINTER_FAULT +\end{lstlisting} + +HEAP теперь является активным selector 0x7. Его low guard 0..15 недоступен для dereference, но это не делает HEAP:0 значением NULL. All-zero DATA:0 остаётся единственным NULL PTR64. + +\subsection{BSWAP: raw byte reversal} +BSWAP имеет opcode 0x0103 и 8-byte machine form: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + BSWAP r<bits>@dst, r<bits>@src +\end{lstlisting} + +OPCODE16 + REG24(dst) + REG24(src) + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + 2 bytes + 3 bytes + 3 bytes = 8 bytes +\end{lstlisting} + +Оба operands обязаны иметь одинаковую физическую ширину. Ассемблер использует именно r<bits> syntax, подчёркивая raw/non-complex interpretation. Допустимы все существующие widths от r8 до r65536. + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + source: b0 b1 b2 ... b(N-2) b(N-1) +\end{lstlisting} + +destination: b(N-1) b(N-2) ... b1 b0 + +r8 является identity. Для r65536 разворачиваются все 8192 bytes. BSWAP не знает, является ли содержимое integer, PTR64, real, complex или частью packed record: операция определена только над физическими байтами. + +PSW invariant. BSWAP не изменяет ни volatile status flags, ни TF/IF/MODE/HF. Width mismatch возвращает CPU\_EXEC\_WIDTH\_FAULT до изменения destination. + +\subsection{In-place и snapshot semantics} +Архитектурно BSWAP определяется как чтение полного source snapshot и только затем запись reversed bytes в destination. Поэтому in-place форма полностью определена: + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + BSWAP r64@0x00100, r64@0x00100 +\end{lstlisting} + +При текущем natural alignment equal-width register views не могут частично перекрываться иначе, чем полностью совпасть. Тем не менее snapshot formulation является нормативной и не зависит от внутренних оптимизаций исполнителя. + +\subsection{External binary formats} +BSWAP не означает «to little endian» или «to big endian». Она лишь разворачивает bytes. Решение о swap принимает программа/tool, сравнивая external format с текущим CPU\_DATA\_BYTE\_ORDER. + +\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize] + ; native target-order value + LDI r64@0x00000, 42 + + ; физически reversed representation (например wire order, если он противоположен target) + BSWAP r64@0x00008, r64@0x00000 + + ; обратное преобразование + BSWAP r64@0x00010, r64@0x00008 +\end{lstlisting} + +Для packed file/protocol records это даёт явное и предсказуемое преобразование. Packed layout и byte order остаются независимыми понятиями: packed убирает padding, BSWAP меняет порядок bytes конкретного field. + |
