x86.txt 25 KB

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