x86_64.txt 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1.  Компилятор языка программирования Oberon-07/16 для x86_64
  2. Windows/Linux
  3. ------------------------------------------------------------------------------
  4. Параметры командной строки
  5. Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
  6. UTF-8 с BOM-сигнатурой.
  7. Выход - испоняемый файл формата PE32+ или ELF64.
  8. Параметры:
  9. 1) имя главного модуля
  10. 2) тип приложения
  11. "win64con" - Windows64 console
  12. "win64gui" - Windows64 GUI
  13. "win64dll" - Windows64 DLL
  14. "linux64exe" - Linux ELF64-EXEC
  15. "linux64so" - Linux ELF64-SO
  16. 3) необязательные параметры-ключи
  17. -out <file_name> имя результирующего файла; по умолчанию,
  18. совпадает с именем главного модуля, но с другим расширением
  19. (соответствует типу исполняемого файла)
  20. -stk <size> размер стэка в мегабайтах (по умолчанию 2 Мб,
  21. допустимо от 1 до 32 Мб)
  22. -tab <width> размер табуляции (используется для вычисления координат в
  23. исходном коде), по умолчанию - 4
  24. -nochk <"ptibcwra"> отключить проверки при выполнении
  25. -lower разрешить ключевые слова и встроенные идентификаторы в
  26. нижнем регистре (по умолчанию)
  27. -upper только верхний регистр для ключевых слов и встроенных
  28. идентификаторов
  29. -def <имя> задать символ условной компиляции
  30. -uses вывести список импортированных модулей
  31. -fa <size> выравнивание секций файла PE32 в байтах, возможные значения:
  32. 512, 1024, 2048, 4096. По умолчанию - 512
  33. параметр -nochk задается в виде строки из символов:
  34. "p" - указатели
  35. "t" - типы
  36. "i" - индексы
  37. "b" - неявное приведение INTEGER к BYTE
  38. "c" - диапазон аргумента функции CHR
  39. "w" - диапазон аргумента функции WCHR
  40. "r" - эквивалентно "bcw"
  41. "a" - все проверки
  42. Порядок символов может быть любым. Наличие в строке того или иного
  43. символа отключает соответствующую проверку.
  44. Например: -nochk it - отключить проверку индексов и охрану типа.
  45. -nochk a - отключить все отключаемые проверки.
  46. Например:
  47. Compiler.exe "C:\example.ob07" win64con -out "C:\example.exe" -stk 1
  48. Compiler.exe "C:\example.ob07" win64dll -out "C:\example.dll" -nochk pti
  49. Compiler "source/Compiler.ob07" linux64exe -out "source/Compiler" -nochk a
  50. В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
  51. ------------------------------------------------------------------------------
  52. Отличия от оригинала
  53. 1. Расширен псевдомодуль SYSTEM
  54. 2. В идентификаторах допускается символ "_"
  55. 3. Добавлены системные флаги
  56. 4. Усовершенствован оператор CASE (добавлены константные выражения в
  57. метках вариантов и необязательная ветка ELSE)
  58. 5. Расширен набор стандартных процедур
  59. 6. Семантика охраны/проверки типа уточнена для нулевого указателя
  60. 7. Добавлены однострочные комментарии (начинаются с пары символов "//")
  61. 8. Разрешено наследование от типа-указателя
  62. 9. Добавлен синтаксис для импорта процедур из внешних библиотек
  63. 10. "Строки" можно заключать также в одиночные кавычки: 'строка'
  64. 11. Добавлен тип WCHAR
  65. 12. Добавлена операция конкатенации строковых и символьных констант
  66. 13. Возможен импорт модулей с указанием пути и имени файла
  67. 14. Добавлен специальный синтаксис для условной компиляции (см. CC.txt)
  68. 15. Имя процедуры в конце объявления (после END) необязательно
  69. 16. Разрешено использовать нижний регистр для ключевых слов
  70. ------------------------------------------------------------------------------
  71. Особенности реализации
  72. 1. Основные типы
  73. Тип Диапазон значений Размер, байт
  74. INTEGER -9223372036854775808 .. 9223372036854775807 8
  75. REAL 4.94E-324 .. 1.70E+308 8
  76. CHAR символ ASCII (0X .. 0FFX) 1
  77. BOOLEAN FALSE, TRUE 1
  78. SET множество из целых чисел {0 .. 63} 8
  79. BYTE 0 .. 255 1
  80. WCHAR символ юникода (0X .. 0FFFFX) 2
  81. 2. Максимальная длина идентификаторов - 255 символов
  82. 3. Максимальная длина строковых констант - 511 символов (UTF-8)
  83. 4. Максимальная размерность открытых массивов - 5
  84. 5. Процедура NEW заполняет нулями выделенный блок памяти
  85. 6. Глобальные и локальные переменные инициализируются нулями
  86. 7. В отличие от многих Oberon-реализаций, сборщик мусора и динамическая
  87. модульность отсутствуют
  88. 8. Тип BYTE в выражениях всегда приводится к INTEGER
  89. 9. Контроль переполнения значений выражений не производится
  90. 10. Ошибки времени выполнения:
  91. 1 ASSERT(x), при x = FALSE
  92. 2 разыменование нулевого указателя
  93. 3 целочисленное деление на неположительное число
  94. 4 вызов процедуры через процедурную переменную с нулевым значением
  95. 5 ошибка охраны типа
  96. 6 нарушение границ массива
  97. 7 непредусмотренное значение выражения в операторе CASE
  98. 8 ошибка копирования массивов v := x, если LEN(v) < LEN(x)
  99. 9 CHR(x), если (x < 0) OR (x > 255)
  100. 10 WCHR(x), если (x < 0) OR (x > 65535)
  101. 11 неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255)
  102. ------------------------------------------------------------------------------
  103. Псевдомодуль SYSTEM
  104. Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
  105. ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
  106. повреждению данных времени выполнения и аварийному завершению программы.
  107. PROCEDURE ADR(v: любой тип): INTEGER
  108. v - переменная или процедура;
  109. возвращает адрес v
  110. PROCEDURE SADR(x: строковая константа (CHAR UTF-8)): INTEGER
  111. возвращает адрес x
  112. PROCEDURE WSADR(x: строковая константа (WCHAR)): INTEGER
  113. возвращает адрес x
  114. PROCEDURE VAL(v: любой тип; T): T
  115. v - переменная;
  116. интерпретирует v, как переменную типа T
  117. PROCEDURE SIZE(T): INTEGER
  118. возвращает размер типа T
  119. PROCEDURE TYPEID(T): INTEGER
  120. T - тип-запись или тип-указатель,
  121. возвращает номер типа в таблице типов-записей
  122. PROCEDURE INF(): REAL
  123. возвращает специальное вещественное значение "бесконечность"
  124. PROCEDURE MOVE(Source, Dest, n: INTEGER)
  125. Копирует n байт памяти из Source в Dest,
  126. области Source и Dest не могут перекрываться
  127. PROCEDURE GET(a: INTEGER;
  128. VAR v: любой основной тип, PROCEDURE, POINTER)
  129. v := Память[a]
  130. PROCEDURE GET8(a: INTEGER;
  131. VAR x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  132. Эквивалентно
  133. SYSTEM.MOVE(a, SYSTEM.ADR(x), 1)
  134. PROCEDURE GET16(a: INTEGER;
  135. VAR x: INTEGER, SET, WCHAR, SYSTEM.CARD32)
  136. Эквивалентно
  137. SYSTEM.MOVE(a, SYSTEM.ADR(x), 2)
  138. PROCEDURE GET32(a: INTEGER; VAR x: INTEGER, SET, SYSTEM.CARD32)
  139. Эквивалентно
  140. SYSTEM.MOVE(a, SYSTEM.ADR(x), 4)
  141. PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER)
  142. Память[a] := x;
  143. Если x: BYTE или x: WCHAR, то значение x будет расширено
  144. до 64 бит, для записи байтов использовать SYSTEM.PUT8,
  145. для WCHAR -- SYSTEM.PUT16
  146. PROCEDURE PUT8(a: INTEGER;
  147. x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  148. Память[a] := младшие 8 бит (x)
  149. PROCEDURE PUT16(a: INTEGER;
  150. x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  151. Память[a] := младшие 16 бит (x)
  152. PROCEDURE PUT32(a: INTEGER;
  153. x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  154. Память[a] := младшие 32 бит (x)
  155. PROCEDURE COPY(VAR Source: любой тип; VAR Dest: любой тип; n: INTEGER)
  156. Копирует n байт памяти из Source в Dest.
  157. Эквивалентно
  158. SYSTEM.MOVE(SYSTEM.ADR(Source), SYSTEM.ADR(Dest), n)
  159. PROCEDURE CODE(byte1, byte2,... : BYTE)
  160. Вставка машинного кода,
  161. byte1, byte2 ... - константы в диапазоне 0..255,
  162. например:
  163. SYSTEM.CODE(048H,08BH,045H,010H) (* mov rax,qword[rbp+16] *)
  164. Также, в модуле SYSTEM определен тип CARD32 (4 байта). Для типа CARD32 не
  165. допускаются никакие явные операции, за исключением присваивания.
  166. Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
  167. ------------------------------------------------------------------------------
  168. Системные флаги
  169. При объявлении процедурных типов и глобальных процедур, после ключевого
  170. слова PROCEDURE может быть указан флаг соглашения о вызове:
  171. [win64], [systemv], [windows], [linux], [oberon], [ccall].
  172. Например:
  173. PROCEDURE [win64] MyProc (x, y, z: INTEGER): INTEGER;
  174. Флаг [windows] - синоним для [win64], [linux] - синоним для [systemv].
  175. Флаг [ccall] - синоним для [win64] или [systemv] (зависит от целевой ОС).
  176. Знак "-" после имени флага ([win64-], [linux-], ...) означает, что
  177. результат процедуры можно игнорировать (не допускается для типа REAL).
  178. Если флаг не указан или указан флаг [oberon], то принимается внутреннее
  179. соглашение о вызове. [win64] и [systemv] используются для связи с
  180. операционной системой и внешними приложениями.
  181. При объявлении типов-записей, после ключевого слова RECORD может быть
  182. указан флаг [noalign]. Флаг [noalign] означает отсутствие выравнивания полей
  183. записи. Записи с системным флагом не могут иметь базовый тип и не могут быть
  184. базовыми типами для других записей.
  185. Для использования системных флагов, требуется импортировать SYSTEM.
  186. ------------------------------------------------------------------------------
  187. Оператор CASE
  188. Синтаксис оператора CASE:
  189. CaseStatement =
  190. CASE Expression OF Case {"|" Case}
  191. [ELSE StatementSequence] END.
  192. Case = [CaseLabelList ":" StatementSequence].
  193. CaseLabelList = CaseLabels {"," CaseLabels}.
  194. CaseLabels = ConstExpression [".." ConstExpression].
  195. Например:
  196. CASE x OF
  197. |-1: DoSomething1
  198. | 1: DoSomething2
  199. | 0: DoSomething3
  200. ELSE
  201. DoSomething4
  202. END
  203. В метках вариантов можно использовать константные выражения, ветка ELSE
  204. необязательна. Если значение x не соответствует ни одному варианту и ELSE
  205. отсутствует, то программа прерывается с ошибкой времени выполнения.
  206. ------------------------------------------------------------------------------
  207. Тип WCHAR
  208. Тип WCHAR добавлен в язык для удобной поддежки юникода. Для типов WCHAR и
  209. ARRAY OF WCHAR допускаются все те же операции, как для типов CHAR и
  210. ARRAY OF CHAR, за исключением встроенной процедуры CHR, которая возвращает
  211. только тип CHAR. Для получения значения типа WCHAR, следует использовать
  212. процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять
  213. исходный код в кодировке UTF-8 с BOM.
  214. ------------------------------------------------------------------------------
  215. Конкатенация строковых и символьных констант
  216. Допускается конкатенация ("+") константных строк и символов типа CHAR:
  217. str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
  218. newline = 0DX + 0AX;
  219. ------------------------------------------------------------------------------
  220. Проверка и охрана типа нулевого указателя
  221. Оригинальное сообщение о языке не определяет поведение программы при
  222. выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
  223. Oberon-реализациях выполнение такой операции приводит к ошибке времени
  224. выполнения. В данной реализации охрана типа нулевого указателя не приводит к
  225. ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
  226. значительно сократить частоту применения охраны типа.
  227. ------------------------------------------------------------------------------
  228. Дополнительные стандартные процедуры
  229. DISPOSE (VAR v: любой_указатель)
  230. Освобождает память, выделенную процедурой NEW для
  231. динамической переменной v^, и присваивает переменной v
  232. значение NIL.
  233. COPY (x: ARRAY OF CHAR/WCHAR; VAR v: ARRAY OF CHAR/WCHAR);
  234. v := x;
  235. Если LEN(v) < LEN(x), то строка x будет скопирована
  236. не полностью
  237. LSR (x, n: INTEGER): INTEGER
  238. Логический сдвиг x на n бит вправо.
  239. MIN (a, b: INTEGER): INTEGER
  240. Минимум из двух значений.
  241. MAX (a, b: INTEGER): INTEGER
  242. Максимум из двух значений.
  243. BITS (x: INTEGER): SET
  244. Интерпретирует x как значение типа SET.
  245. Выполняется на этапе компиляции.
  246. LENGTH (s: ARRAY OF CHAR/WCHAR): INTEGER
  247. Длина 0X-завершенной строки s, без учета символа 0X.
  248. Если символ 0X отсутствует, функция возвращает длину
  249. массива s. s не может быть константой.
  250. WCHR (n: INTEGER): WCHAR
  251. Преобразование типа, аналогично CHR(n: INTEGER): CHAR
  252. ------------------------------------------------------------------------------
  253. Импорт модулей с указанием пути и имени файла
  254. Примеры:
  255. IMPORT Math IN "./lib/math.ob07"; (* относительно текущего модуля *)
  256. IMPORT M1 IN "C:\lib\math.ob07"; (* абсолютный путь *)
  257. ------------------------------------------------------------------------------
  258. Импортированные процедуры
  259. Синтаксис импорта:
  260. PROCEDURE [callconv, library, function] proc_name (FormalParam): Type;
  261. - callconv -- соглашение о вызове
  262. - library -- имя файла динамической библиотеки (строковая константа)
  263. - function -- имя импортируемой процедуры (строковая константа), если
  264. указана пустая строка, то имя процедуры = proc_name
  265. например:
  266. PROCEDURE [windows, "kernel32.dll", "ExitProcess"] exit (code: INTEGER);
  267. PROCEDURE [windows, "kernel32.dll", ""] GetTickCount (): INTEGER;
  268. В конце объявления может быть добавлено (необязательно) "END proc_name;"
  269. Объявления импортированных процедур должны располагаться в глобальной
  270. области видимости модуля после объявления переменных, вместе с объявлением
  271. "обычных" процедур, от которых импортированные отличаются только отсутствием
  272. тела процедуры. В остальном, к таким процедурам применимы те же правила:
  273. их можно вызвать, присвоить процедурной переменной или получить адрес.
  274. Так как импортированная процедура всегда имеет явное указание соглашения о
  275. вызове, то совместимый процедурный тип тоже должен быть объявлен с указанием
  276. соглашения о вызове:
  277. VAR
  278. ExitProcess: PROCEDURE [windows] (code: INTEGER);
  279. Для Linux, импортированные процедуры не реализованы.
  280. ------------------------------------------------------------------------------
  281. Скрытые параметры процедур
  282. Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
  283. формальных параметров, но учитываются компилятором при трансляции вызовов.
  284. Это возможно в следующих случаях:
  285. 1. Процедура имеет формальный параметр открытый массив:
  286. PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL);
  287. Вызов транслируется так:
  288. Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x))
  289. 2. Процедура имеет формальный параметр-переменную типа RECORD:
  290. PROCEDURE Proc (VAR x: Rec);
  291. Вызов транслируется так:
  292. Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
  293. Скрытые параметры необходимо учитывать при связи с внешними приложениями.
  294. ------------------------------------------------------------------------------
  295. Модуль RTL
  296. Все программы неявно используют модуль RTL. Компилятор транслирует
  297. некоторые операции (проверка и охрана типа, сравнение строк, сообщения об
  298. ошибках времени выполнения и др.) как вызовы процедур этого модуля. Не
  299. следует вызывать эти процедуры явно.
  300. Сообщения об ошибках времени выполнения выводятся в диалоговых окнах
  301. (Windows), в терминал (Linux).
  302. ------------------------------------------------------------------------------
  303. Модуль API
  304. Существуют несколько реализаций модуля API (для различных ОС).
  305. Как и модуль RTL, модуль API не предназначен для прямого использования.
  306. Он обеспечивает связь RTL с ОС.
  307. ------------------------------------------------------------------------------
  308. Генерация исполняемых файлов DLL
  309. Разрешается экспортировать только процедуры. Для этого, процедура должна
  310. находиться в главном модуле программы, ее имя должно быть отмечено символом
  311. экспорта ("*") и должно быть указано соглашение о вызове. Нельзя
  312. экспортировать процедуры, которые импортированы из других dll-библиотек.