О формате объектных файлов и библиотек COFF и OMF, и об опасности их смешения.

На рассвете цивилизации ПК и примерно до того времени, когда появились инструменты программирования Microsoft Win32, почти все компиляторы для ПК создавали объектные файлы с использованием стандарта Intel Object Module Format (OMF). Позже Intel представила процессоры 386 и 32-разрядный защищенный режим, после чего они также расширили спецификацию OMF для 32-разрядных систем, что привело к появлению «OMF-386», который стал стандартом для большинства сред защищенного режима ПК. Примерно в это же время исходная группа разработчиков Windows NT также разрабатывала код не только для процессоров Intel, но и для поддержки процессоров других производителей. Команда Microsoft NT выбрала более переносимый формат объектных модулей, известный как Common Object File Format (COFF), производный от официального формата объектного кода для UNIX System V. Объектные модули COFF позже стали стандартом де-факто для всех инструментов разработки Microsoft Win32 и получили преимущество в том, что он намного ближе по формату к переносимым исполняемым файлам (PE) — собственному исполняемому формату для Win32 (компоновщику формата COFF требуется гораздо меньше усилий для создания 32-разрядного EXE или DLL из файла COFF, чем из файла формата OMF).

Помимо объектных файлов форматов OMF и COFF (.obj), существуют также файлы библиотек форматов OMF и COFF (.lib). Библиотеки, к счастью, в основном представляют собой просто набор объектных файлов вместе с заголовочной информацией, которая позволяет компоновщику определить, какие объектные файлы из библиотеки использовать. Однако, чтобы усложнить ситуацию, и OMF, и COFF используют одни и те же расширения имен файлов, .obj и .lib, для ссылки на два разных типа форматов файлов объектов и библиотек (из-за этого вы не можете просто посмотреть на расширение имени файла чтобы узнать, является ли объектный модуль или файл библиотеки OMF или COFF).

Проблема со смешиванием объектных файлов и файлов библиотек от разных производителей компиляторов заключается в том, что одни поставщики поддерживают COFF, другие используют OMF, а некоторые могут работать и с тем, и с другим. Borland, например, по-прежнему использует объектные файлы и библиотеки OMF, тогда как 32-разрядные компиляторы Microsoft создают файлы формата COFF. Watcom C/C++ v11.0, по-видимому, предпочитает COFF при компиляции и компоновке приложений Windows, но создает объектные файлы OMF для использования с 32-разрядным DOS-расширителем защищенного режима DOS4GW. Microsoft MASM 6.13 по умолчанию создает файлы OMF, но параметр командной строки /coff указывает компилятору, что он должен создавать объектные файлы COFF.

Когда приходится связывать файлы разных форматов, разные компоновщики делают разные вещи. Например, компоновщик Microsoft Visual C/C++ предназначен для объектных файлов и библиотек формата COFF, но при необходимости попытается преобразовать объектные файлы OMF в файлы COFF. В некоторых случаях это работает, но, к сожалению, Microsoft LINK не поддерживает все типы записей OMF, поэтому во многих ситуациях компоновщик может дать сбой при работе с объектными файлами формата OMF. Кроме того, хотя Microsoft LINK пытается поддерживать объектные файлы OMF, он отказывается обрабатывать любые библиотеки формата OMF. Другие компоновщики, такие как TLINK от Borland, предназначены для объектных файлов OMF и аналогичным образом отказываются работать с объектными или библиотечными файлами формата COFF. Некоторые поставщики расширителей DOS и встраиваемых систем, такие как Phar Lap, предоставляют свои собственные компоновщики, поддерживающие как OMF, так и COFF, что дает вам возможность выбора.

Проблема в том, что смешение OMF и COFF типов объектных файлов и файлов библиотек может привести к хаосу. Вдобавок появляются загадочные сообщения об ошибках от компоновщиков, которые только вносят еще большее непонимание. Если ваш компоновщик не поддерживает определенный формат, вам следует придерживаться рекомендуемого формата объекта и библиотеки для вашего компилятора/компоновщика/платформы и избегать смешивания файлов OMF и COFF.

Перевод: Leha Silent для tolik-punkoff.com
Оригинальный текст (англ., TXT) предоставил Jiang Yap из WeChat
Копия перевода в TXT

Assembler: проверка условий и переходы (jump)

Небольшая шпаргалка по условным и безусловным переходам.

Безусловный переход: выполняется командой JMP <метка>, может использоваться, как для перехода вперед, пропуская некоторые команды в коде, так и для возврата назад, для повторного выполнения инструкций:

1.

	...
	какой-то код
	...
	JMP	label1
	...
	какой-то код
	...
label1:
	...
	другой код
	выполняется после срабатывания
	инструкции JMP
	...


2.

	...
	какой-то код
	...
labelret:
	...
	какой-то код
	...
	JMP	labelret

Условный переход: Выполняется, если выполнено какое-либо условие, переход осуществляется командой Jxx <метка>, где xx — мнемоника, указывающая на проверяемое условие.

Инструкция CMP

Инструкция CMP сравнивает два операнда, в основном вычитая один операнд из другого для сравнения, равны ли операнды или нет, не изменяя целевой или исходный операнд. Инструкция CMP используется вместе с инструкцией условного перехода для принятия решения. CMP изменяет регистр флагов, который потом проверяет соответствующая инструкция условного перехода, и осуществляет (не осуществляет) переход по соответствующему адресу (метке).

Синтаксис:

CMP целевой_операнд, исходный_операнд

CMP сравнивает два числа. В качестве целевого операнда может использоваться значение в регистре или в памяти. Исходный операнд может быть константой (EQU), непосредственно числом, значением в регистре или памяти. Так же, оба операнда не могут быть одновременно значениями в памяти.

Правильно Неправильно Ошибка (MASM)
cmp eax, ecx MYVALUE1 dd 2
MYVALUE2 dd 5

cmp MYVALUE1, MYVALUE2
invalid instruction operands
cmp eax, 0 cmp 0, eax immediate operand not allowed
ERROR_FLAG EQU 16h

cmp eax, ERROR_FLAG
ERROR_FLAG EQU 16h

cmp ERROR_FLAG, eax
immediate operand not allowed
MYVALUE dd ?

cmp eax, MYVALUE
MYVALUE dd ?

cmp MYVALUE, eax
MYVALUE dd ?

cmp MYVALUE, 0
MYVALUE dd ?

cmp 0, MYVALUE
immediate operand not allowed
MYVALUE dd ?
ERROR_FLAG EQU 16h

cmp MYVALUE, ERROR_FLAG
MYVALUE dd ?
ERROR_FLAG EQU 16h

cmp ERROR_FLAG, MYVALUE
immediate operand not allowed
cmp 0, 1 immediate operand not allowed
CONST1 equ 1
CONST2 equ 2

cmp CONST1, CONST2
immediate operand not allowed

Также нужно быть внимательным при сравнении значения в памяти и регистре, если их размерность будет не совпадать, это приведет к ошибке компиляции. Например, при сравнении регистра EAX, имеющего разрядность двойное слово (DWORD) с переменной, разрядность которой установлена, как байтовая (DB):

...
MYVALUE db 1
...
cmp eax, MYVALUE
...
;Ошибка: invalid instruction operands

Условные переходы

Результаты арифметических операции для знаковых чисел

Инструкция Описание Проверяемые флаги
JE/JZ Если значения равны/Если значение 0 ZF
JNE/JNZ Если значения не равны/Если значение не 0 ZF
JG/JNLE Если больше/Если не меньше или равно OF SF ZF
JGE/JNL Если больше или равно/Если не меньше OF SF
JL/JNGE Если меньше/Если не больше или равно OF SF
JLE/JNG Если меньше или равно/Если не больше OF SF ZF

Результаты арифметических операции для беззнаковых чисел или логических операций

Инструкция Описание Проверяемые флаги
JE/JZ Если значения равны/Если значение 0 ZF
JNE/JNZ Если значения не равны/Если значение не 0 ZF
JA/JNBE Если больше/Если не меньше или равно CF ZF
JAE/JNB Если больше или равно/Если не меньше CF
JB/JNAE Если меньше/Если не больше или равно CF
JBE/JNA Если меньше или равно/Если не больше AF CF

Прочие инструкции для условных переходов

Эти инструкции имеют специальное применение и проверяют значения отдельных флагов во флаговом регистре.

Инструкция Описание Проверяемые флаги
JXCZ Если значение в регистре CX равно 0 Нет
JC Если произошел перенос в результате арифметической операции CF
JNC Перенос не произошел CF
JO Произошло переполнение OF
JNO Переполнение не произошло OF
JP/JPE Число единичных бит четное PF
JNP/JPO Число единичных бит нечетное PF
JS Число со знаком (отрицательное) SF
JNS Число без знака (положительное) SF

Ссылки

Регистр флагов с описанием значений флагов (копия)