summaryrefslogtreecommitdiff
path: root/doc/src/libmcpu-assembler-details-ru.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/libmcpu-assembler-details-ru.tex')
-rw-r--r--doc/src/libmcpu-assembler-details-ru.tex233
1 files changed, 233 insertions, 0 deletions
diff --git a/doc/src/libmcpu-assembler-details-ru.tex b/doc/src/libmcpu-assembler-details-ru.tex
new file mode 100644
index 0000000..75a5c4a
--- /dev/null
+++ b/doc/src/libmcpu-assembler-details-ru.tex
@@ -0,0 +1,233 @@
+\section{Ассемблер: UTF-8 source, строки, .equ и arithmetic expressions}
+Низкоуровневый mcpu-as обязан уметь описывать binary images data-like sections, labels и relocation-like address expressions без обязательного текстового препроцессора. Текстовая метапрограмма (\#define, \#include, conditional compilation, parameterized macros) остаётся отдельным будущим слоем. В assembler входят только механизмы, непосредственно связанные с machine/data representation и разрешением символов.
+
+\subsection{Кодировка assembler source}
+Исходный файл mcpu-as всегда UTF-8. Результат сборки не зависит от LANG, LC\_CTYPE или другой locale host-системы. Перед разбором assembler проверяет source как well-formed UTF-8 через LibMPUIO.
+
+Это особенно важно для строковых директив: одинаковый .s обязан создавать одинаковые image bytes на любых build hosts при одинаковом LibMCPU target profile.
+
+\subsection{Командная строка mcpu-as}
+Ассемблер всегда создаёт один перемещаемый объект MELF ET\_REL, поэтому отдельный переключатель режима сборки не нужен. Выходной файл задаётся обычной UNIX-опцией \code{-o}, а единственный исходный файл является позиционным аргументом:
+
+\begin{lstlisting}[language={}]
+mcpu-as -o file.o file.s
+mcpu-as file.s -o file.o
+\end{lstlisting}
+
+Обе формы полностью эквивалентны: порядок \code{-o} и входного файла свободный. Ровно один входной файл и ровно один выходной файл обязательны. Опции \code{-h} и \code{--help} печатают справку. Историческая форма \code{mcpu-as -c input.s output.o} удалена: \code{-c} больше не является опцией, поскольку другого режима работы у assembler нет.
+
+\subsection{.utf8 - NUL-terminated UTF-8 byte string}
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .data
+\end{lstlisting}
+
+name\_utf8:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .utf8 "Андрей"
+\end{lstlisting}
+
+.utf8 записывает UTF-8 payload буквально как bytes и добавляет один завершающий 0x00. Никакого target endian преобразования и никакой locale conversion нет.
+
+"Андрей" -> D0 90 D0 BD D0 B4 D1 80 D0 B5 D0 B9 00
+
+Поддерживаются escapes \textbackslash{}\textbackslash{}, \textbackslash{}", \textbackslash{}n, \textbackslash{}r, \textbackslash{}t, \textbackslash{}b, \textbackslash{}f, \textbackslash{}v, \textbackslash{}a, byte escape \textbackslash{}xHH, а также Unicode scalar escapes \textbackslash{}uXXXX и \textbackslash{}UXXXXXXXX. Результирующая последовательность снова проверяется как UTF-8.
+
+Встроенный NUL внутри .utf8/.ucs2 намеренно не поддерживается: эти директивы определяют C-style NUL-terminated strings. Для произвольного binary layout с внутренними нулями используется .byte или .integer/.int.
+
+\subsection{.ucs2 - UTF-8 source literal в strict UCS-2 target objects}
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .data
+\end{lstlisting}
+
+name\_ucs2:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .ucs2 "Андрей"
+\end{lstlisting}
+
+Assembler сначала получает UTF-8 literal, затем использует strict LibMPUIO UTF-8 -> UCS-2 conversion. Каждый UCS-2 code unit записывается как отдельный 16-bit architectural data object с помощью target data byte order; в конце добавляется U+0000.
+
+U+0410 U+043D U+0434 U+0440 U+0435 U+0439 U+0000
+
+current little-endian target bytes:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ 10 04 3D 04 34 04 40 04 35 04 39 04 00 00
+\end{lstlisting}
+
+Strict UCS-2 допускает scalar values U+0000..U+FFFF, кроме surrogate range U+D800..U+DFFF. UTF-8 characters выше U+FFFF (например emoji) не раскладываются на UTF-16 surrogate pairs, а дают assembler error. Таким образом .ucs2 точно соответствует принятой в LibMCPU/LibMPUIO модели UCS-2, а не UTF-16.
+
+\subsection{.byte, .integer и .int}
+.byte создаёт raw bytes без implicit terminator, alignment или endian conversion:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .byte 0x4c, 0x43, 0x50, 0x55
+ .byte 1, 2+3, BLOCK_SIZE/512
+\end{lstlisting}
+
+Каждый элемент должен находиться в диапазоне 0..255. .integer сохраняет прежний смысл typed integer object, а .int является полным синонимом. Обе директивы принимают список значений одной ширины:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .integer 16, 0x0410, 0x043d, 0x0000
+ .int 8, 65, 66, 0
+\end{lstlisting}
+
+Каждое значение формирует отдельный object указанной width непосредственно в текущей data-like section position; hidden padding отсутствует.
+
+\subsection{.equ - абсолютные assembler symbols}
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .equ table_ptr, 0x03000
+ .equ block_size, 4 * 512
+ .equ next_reg, table_ptr + 8
+\end{lstlisting}
+
+.equ section-independent и не создаёт bytes. Имена symbols case-sensitive. Все .equ definitions собираются до emission, поэтому разрешены forward references между .equ symbols.
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .equ является absolute constant symbol. В текущем low-level assembler выражение
+\end{lstlisting}
+
+справа может ссылаться на integer literals и другие .equ, но не на DATA/CODE labels. Это сохраняет различие между absolute assembler symbols и section-relative labels/relocations MELF.
+
+Имя label не может совпадать с именем .equ.
+
+\subsection{Integer expression grammar и precedence}
+primary := integer | symbol | '(' expression ')'
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ unary := ['+' | '-'] unary | primary
+\end{lstlisting}
+
+product := unary \{ ('*' | '/' | '\%') unary \} expression := product \{ ('+' | '-') product \}
+
+Операции имеют обычный arithmetic precedence: unary, затем multiply/divide/remainder, затем add/subtract. Division by zero, overflow internal expression domain и значение вне требуемой width дают assembler error.
+
+Expressions используются для absolute numeric operands: register byte address, LDI, stack/pointer signed offsets, BMOVI count, .align, .byte, integer widths/values и других соответствующих immediate fields.
+
+\subsection{Label expressions и fixups}
+Address expressions дополнительно получают labels тех sections, которые допустимы для конкретного operand class. Поэтому assembler непосредственно поддерживает:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ LEA r64@table_ptr, input_vector+8 ; selector follows label section
+ LOAD r64@next_reg, data_object+16 ; direct LOAD remains DATA-relative
+ JMP loop+0 ; PROGRAM CODE64
+ CALL function
+ .cptr handler+0
+\end{lstlisting}
+
+LEA принимает labels из DATA/CONTROL/INPUT/OUTPUT/TRACE и code sections и создаёт полный PTR64 selector+offset. Direct LOAD/STORE остаются в namespace DATA labels + .equ. CODE64 operands и .cptr используют PROGRAM labels + .equ. Forward labels работают через fixups. CPU по-прежнему не хранит instruction-boundary metadata: arithmetic CODE expression обязано использоваться программистом осмысленно.
+
+\subsection{Symbolic register addresses}
+REG24 byte address может быть integer expression из absolute .equ symbols:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .equ table_ptr, 0x03000
+ .equ temp_ptr, table_ptr + 8
+
+ LEA r64@table_ptr, table
+ LDI r64@temp_ptr, 42
+ LDI r64@(table_ptr + 16), 7
+\end{lstlisting}
+
+После вычисления expression assembler выполняет обычную проверку register width, natural alignment и границ 512 KiB register file. DATA/CODE labels в register-address expression не участвуют: label address и register-file byte address являются разными namespaces.
+
+\subsection{Граница mcpu-as и будущего препроцессора}
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ Механизм Уровень Причина
+
+ .init/.text/.fini/.data/.control/.input/.output/.trace, mcpu-as определяют layout
+ labels, .align executable/data
+ images
+
+ .integer/.int/.real/.complex/.byte/.utf8/.ucs2/.cptr mcpu-as создают data-like
+ objects/bytes
+
+
+
+
+
+ .equ, arithmetic expressions, symbol fixups mcpu-as необходимы для
+ адресов и будущих
+ relocations
+
+ #define/#undef/#include/#if/#ifdef отдельный текстовая
+ preprocessor metaprogramming не
+ является machine
+ encoding
+
+ parameterized macros / repetition отдельный source transformation
+ preprocessor до mcpu-as
+\end{lstlisting}
+
+Таким образом обычный symbolic assembler остаётся самодостаточным, а будущая схема .S -> cpu-cpp -> mcpu-as может добавляться независимо и не усложняет binary semantics cpu-as.
+
+\subsection{Полный пример}
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .equ table_ptr, 0x03000
+ .equ next_reg, table_ptr + 8
+ .equ block_size, 4 * 512
+
+ .data
+\end{lstlisting}
+
+name16:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .ucs2 "Андрей"
+\end{lstlisting}
+
+name8:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .utf8 "Андрей"
+\end{lstlisting}
+
+header:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .byte 0x4c, 0x43, 0x50, 0x55, block_size/512
+\end{lstlisting}
+
+letters:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .int 16, 0x0410, 0x043d, 0x0434, 0
+ .align 16
+\end{lstlisting}
+
+answer:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ .integer 64, 42
+
+ .text
+\end{lstlisting}
+
+start:
+
+\begin{lstlisting}[language={},basicstyle=\ttfamily\scriptsize]
+ LEA r64@table_ptr, name16
+ LOAD r64@next_reg, answer
+ HALT
+\end{lstlisting}
+
+Здесь ни один identifier не требует textual macro substitution: table\_ptr/next\_reg - absolute assembler symbols, name16/answer - DATA labels, а arithmetic expression вычисляется самим assembler.
+
+
+\subsection{Маркеры строк препроцессора и логические координаты diagnostics}
+После появления \code{mcpu-cpp} assembler не использует собственную директиву \code{\#line} для управления source coordinates. Вместо неё \code{mcpu-as} распознаёт маркеры строк, оставляемые препроцессором в выходном потоке:
+\begin{lstlisting}[language={}]
+# digit-sequence
+# digit-sequence "filename"
+# digit-sequence "filename" flags...
+\end{lstlisting}
+\code{digit-sequence} содержит как минимум одну decimal digit и всегда разбирается в основании 10, даже при leading zeroes. Допустимый диапазон - 0..2147483647. Значение задаёт logical line number для physical source line, непосредственно следующей за marker. Filename optional; при его отсутствии сохраняется предыдущий logical filename. Всё после закрывающей кавычки filename считается полем flags препроцессора и полностью игнорируется assembler.
+
+Marker не создаёт bytes, symbols, \code{__LINE__} или \code{__FILE__}, не участвует в expression evaluation и влияет только на source coordinates последующих diagnostics. Empty и comment-only ordinary lines увеличивают logical counter обычным образом.
+
+Строки \code{\#pragma} и \code{\#lang} предназначены для других участников toolchain: \code{mcpu-as} полностью игнорирует их и не увеличивает logical line counter. Любая другая строка, начинающаяся с \code{\#}, также удаляется из assembler token stream, но учитывается как одна ordinary logical source line.
+
+\begin{normative}
+\textbf{Историческая форма \#line.} Запись \code{\#line N "file"} больше не является source-location directive \code{mcpu-as}. Она обрабатывается как обычная неизвестная строка \code{\#...}: игнорируется как assembler syntax и учитывается при продвижении logical counter. Координаты source задаются только preprocessing line marker формой \code{\# N "file" flags...}. Это diagnostics contract и не часть MELF ABI.
+\end{normative}