Почему несколько инструкций с одинаковым кодом операции и работают? - PullRequest
4 голосов
/ 06 августа 2011

Я смотрел на инструкции и соответствующие им коды операций. Такие инструкции, как "je" и "jz", имеют одинаковый код операции:

je,jz - 0x74 (8 bit)
je,jz - 0x0f84 (16/32 bit).

Почему у нас такие избыточные инструкции?

Это потому, что это облегчает ассемблерное кодирование? То есть легче понять «прыгать, если равен» в некоторых случаях и «прыгать на ноль» в других случаях. Но сейчас мы не пишем код на ассемблере, так что это поможет?

Ответы [ 5 ]

8 голосов
/ 06 августа 2011

Какая старая цитата из той книги по компьютерной архитектуре, которую мы все имели в школе?«В x86 нет ничего плохого, просто многое из этого не имеет смысла».

Чтобы ответить на ваш вопрос: скорее всего, потому что «переход на ноль» и «прыжок при равенстве» - оба переходы кадрес получателя, основанный на результатах предыдущей инструкции.Тем не менее, результат предыдущей инструкции устанавливает нулевой флаг (ZF) в 1. JZ может быть для «математики», а JE может для «сравнения».Таким образом, с точки зрения программиста, имеет смысл использовать две мнемоники.Возможно, писатели-ассемблеры первых дней пытались имитировать другой популярный язык ассемблера.

Глядя на руководство Intel x86 для Jcc (набор инструкций условного перехода), мы видим, что как JZ, так и JE по существу означают «Переход рядом, если равен (ZF = 1)».И затем в документах фактически упоминается, что это является общим для некоторых наборов инструкций перехода.

Поскольку определенное состояние флагов состояния иногда может интерпретироваться двумя способами, для некоторых кодов операций определяются две мнемоники.Например, инструкция JA (переход, если выше) и инструкция JNBE (переход, если не ниже или равно) являются альтернативной мнемоникой для кода операции 77H.

5 голосов
/ 06 августа 2011

Это просто разные синонимы для одной и той же инструкции. Инструкция просто разветвляется на основе флага Z. Флаг Z устанавливается, если результат инструкции сравнения равен true. Он также устанавливается, если вы проверяете значение, которое оказывается равным нулю.

2 голосов
/ 07 августа 2011

Почему некоторые носители английского говорят, что грузовик, а другие - грузовик?Должны ли мы заставить всех соответствовать одному стандарту?Все гамбургеры должны быть большими маками ...

Сначала мы все еще делаем программу на ассемблере.Достаточно людей делают так, что другие не должны.Ваши компиляторы сильно полагаются на это.Сложно разработать и отладить компиляторы и процессоры без этого.Без компиляторов и процессоров, что бы мы делали?

Тривиально, чтобы синтаксический анализатор ассемблера принимал переход, если равен равен переходу, если установлен нулевой бит, это одна и та же функция, та же инструкция.Люди, которые понимают и используют флаги (при условии, что флаг z прост, но со знаком не переносятся, не имеют) не любят использовать флаги «переходить при переносе», «переходить при нулевом значении» и т. Д. Люди, которые думают с точки зрения отношения для этих конкретных чиселдля этой конкретной операции хотите увидеть прыжок, если равен прыжок, если больше, чем прыжок, если меньше, и так далее.Я бы предпочел избавиться от прыжка, если он равен, прыгать, если меньше, и так далее, и просто иметь флаги, прыгать, если c установить прыжок, если c сбросить, прыгать, если n == v прыгать, если n! = V и т. Д.

Intel - не первая и не последняя архитектура, где вы увидите это.Я полагаю, по той же причине, некоторые люди думают с точки зрения того, что бит в регистре состояния включен или выключен, а другие думают, что это больше.Это возрастная вещь в том смысле, что знание флага z означает, что равенство существует уже до тех пор, пока у процессоров был флаг z, но это не имеет никакого отношения ни к возрасту семейства x86, ни к его набору глупых команд.Такая дружелюбность к разработчикам привлекает разработчиков к вашему процессору, это просто реализовать в инструментах.

Если вы действительно хотите позаботиться об этом, почему существует синтаксис Intel и AT & T для одного и того же набора команд?Это безумие выходит далеко за пределы скачка, если равен (нулевой бит установлен) против скачка, если нулевой бит установлен, и кодирование равно прыжку, если нулевой бит установлен в инструкции.

2 голосов
/ 06 августа 2011

Даже если в наше время он не используется много, язык ассемблера Intel старый. Помните, что оригинальные процессоры 8086 и 8088 относятся к 1970-м годам ...

Когда-то, когда мы все еще писали на ассемблере для таких вещей, как IBM PC / XT, было много смысла иметь несколько инструкций, таких как

CMP  AX, BX
JE   Somewhere

или

AND  AX, BX
JZ   somewhere_else

То, что они оказались в одной и той же инструкции по оборудованию, не важно.

1 голос
/ 06 августа 2011

Хотя это не самый широко используемый язык программирования сегодня, он все еще используется. g ++ может компилировать ассемблерный код. Если вы знаете, что делаете, это дает вам определенное преимущество в скорости.

Что касается вашего вопроса, да, вы правы. В зависимости от обстоятельств помогает так или иначе думать, что приводит к тому, что разные инструкции имеют один и тот же код операции.

...