#ассемблер #процессор
Здравствуйте! Для начала хочу прояснить как я понимаю работу процессора, поправьте, если что-то не так. Грубо: Процессору даётся команда считывания инструкции, вводиться сама инструкция, её код(ну из 0 и 1), потом процессор сопоставляет введённую инструкцию с инструкциями, записанными в нём, получает операнды(если такие есть), и делает, то что должна делать эта инструкция. Вопрос: Возможно ли как-то скомпилировать програму с не валидной инструкцией, заставить процессор перейти к ней. Если да, то что произойдёт? Просто сверит, не найдёт соответствия и всё?Предусмотрено ли такая ситуация? Архитектура не важна, ARM,X86
Ответы
Ответ 1
В случае несуществующей инструкции возникает исключение (прерывание) с определённым номером (int 6). В стеке хранится адрес возврата. По этому адресу можно "вручную" програмно выполнить иснтрукцию, сдвинуть ip-адрес возврата, и сделать возврат iret (для x86) на следущюю инструкцию. Таким образом делалось, к примеру, эмуляция сопроцессора. При этом нужно точно знать как выполнить инструкцию. Для процессора ARM режим исключения (ловушка) по несуществующей инструкции возможно тоже есть. Для ARM7 вектор 0x4 Что будет если встретилась такая инструкция: Если сделать пустой обработчик - процессор повиснет. Как вариант можно написать "программа выполнила недопустимую инструкцию и будет закрыта" (многие версии Windows так делают). Если есть эмуляция - команду выполнит эмулятор Теперь о том зачем эмуляция команд. Случай с x86 486. Там есть замечательная команда bswap eax; которую не поддерживает 386. Зараннее зная что эту команду нужно выполнять, мы пишем программу, вешаем её на прерывание по несуществующей команде, где если data[(e)ip] = код_bswap то выполняем обмен внутри eax. Потом смещаем (e)ip на длинну команды делаем возврат. Как вариант можно эмулировать mmx расширение. Можно на intel эмулировать команды amd и наоборот. Но это будет касатся только даной платформы. Теперь об АРМ. Есть программа для ARM7, теоретически её можно выполнять на ARM6 если знать все недостающие команды в этой платформе и реализовать их выполнение в виде процедур. О кроссплатформенности. Команды для x86 и команды ARM никогда по кодам не пересекутся. Поэтому обработка несуществующих команд будет для каждого процессора своя. Да, можно с помощью #define разграничить и заточить с++ на две три разные платформы реализовав решение в разных файлах - да, и возможно как-то обьеденить всё в proc1(PTR * addr, REGS * reg) но даже регистры у процессоров разные. Поэтому смысла особого в этом нет. Для каждой платформы процессора прийдётся писать свою неповторимую эмуляцию, которая учёт особенности именно этой конкретной архитектуры. Возможно ли как-то скомпилировать програму с не валидной инструкцией? Ответ да, если у процессора существуют такие (есть процессоры где всё пространство инструкций заполнено и таковых нет, как правило RISC архитектуры). это будет только тогда, когда ПО собирается под одну версию ахитектуры, а выполняется на другой (например собрали под 486 а выполняется на 286, или собрали под Pentium-III, а выполняем на Pentium-II), или намерено генерируем код не под ту платформу под которую собрано (с помощью __emit__ или выполняем команды в массиве). Но обычно так не делают. Что б программа заработала, на уровне ядра OS делают эмуляцию. И последнее - емуляция значительно замедляет выполнение:). В контексте исключительных ситуаций процессора применяется три понятия, которые часто в литературе могут быть как "синонимами" так и разными понятиями (что иногда вызывает путаницу): interrupt (int сокращённо) - прерывание (как по исключению так и нет), trap - ловушка (имеется ввиду исключительной ситуации), exception - исключение.
Комментариев нет:
Отправить комментарий