Я думаю, что все дают вам один и тот же ответ. Набор команд - это набор (как в математике) всех инструкций, которые процессор может выполнить или понять. Ассемблер является языком программирования.
Позвольте мне попробовать некоторые примеры, основанные на некоторых из вопросов, которые вы задаете. И я собираюсь прыгать с процессора на процессор с любым удобным для меня кодом.
Инструкция или код операции, двоичный или машинный язык, любой термин, который вы хотите использовать для битов / байтов, которые загружаются в процессор для декодирования и выполнения. Пример
0x5C0B
Язык ассемблера, будет
add r12,r11
Для этого конкретного процессора. В данном случае это означает, что r11 = r11 + r12. Поэтому я поместил этот текст, добавить r12, r11 в текстовый файл и использую ассемблер (программу, которая компилирует / ассемблирует язык ассемблера), чтобы собрать его в некоторый вид двоичного файла. Как и любой язык программирования, иногда вы создаете объектные файлы, а затем связываете их вместе, иногда вы можете перейти прямо к двоичному файлу. И есть много форм двоичных файлов, которые находятся в ascii и двоичных формах, и совсем другое обсуждение.
Теперь, что вы можете сделать в ассемблере, который не является частью набора команд? Чем они отличаются? Ну, для начала вы можете иметь макросы:
.macro add3 arg1, arg2, arg3
add \arg1,\arg3
add \arg2,\arg3
.endm
.text
add3 r10,r11,r12
Макросы похожи на встроенные функции, они не являются вызываемыми функциями, а генерируют код в строке. Не отличается от макроса C, например. Таким образом, вы можете использовать их, чтобы сохранить некоторую типизацию, или вы можете использовать их, чтобы абстрагировать что-то, что вы хотите делать снова и снова, и хотите, чтобы способность изменялась в одном месте и не приходилось касаться каждого экземпляра. Приведенный выше пример по существу генерирует это:
add r10,r12
add r11,r12
Другим отличием между набором команд и языком ассемблера являются псевдоинструкции, например, для этого конкретного набора инструкций нет поп-инструкции для выталкивания вещей из стека, по крайней мере, не по этому имени, и я объясню почему. Но вам разрешено сохранять некоторые данные и использовать в своем коде всплывающее окно:
pop r12
Причина, по которой отсутствует всплывающее окно, заключается в том, что режимы адресации достаточно гибкие, чтобы считывать адрес из регистра источника, записывать значение в регистр назначения и увеличивать регистр источника на слово. Который в ассемблере для этого набора команд
mov @r1+,r12
и pop, и mov приводят к коду операции 0x413C.
Другой пример различий между набором команд и ассемблером, переключением наборов команд, выглядит примерно так:
ldr r0,=bob
Что для этого языка ассемблера означает загрузку адреса bob в регистр 0, для этого нет инструкции, что ассемблер делает с ним, генерирует что-то, что выглядело бы так, если бы вы писали его в ассемблере вручную:
ldr r0,ZZ123
...
ZZ123: .word bob
По существу, в доступном месте из этой инструкции, а не в пути выполнения, создается слово, которое компоновщик заполнит адресом для bob. Инструкция ldr, аналогично ассемблеру или компоновщику, будет закодирована с помощью ldr относительной инструкции pc.
Это приводит к целой категории различий между набором команд и языком ассемблера
call fun
Машинный код не может знать, что такое веселье и где его найти. Для этого набора команд с его многими режимами адресации (заметьте, я специально и намеренно избегаю называть наборы инструкций, которые я использую, поскольку это не имеет отношения к обсуждению), ассемблер или компоновщик в зависимости от обстоятельств (в зависимости от того, где заканчивается функция fun быть по отношению к этой инструкции).
Ассемблер может выбрать кодирование этой инструкции как относительного pc, если функция fun на 40 байт опережает инструкцию call, он может закодировать ее с помощью эквивалента call pc + 36 (снять четыре, потому что pc впереди одной инструкции во время выполнения, и это 4-байтовая инструкция).
Или ассемблер может не знать, где или что интересного, и оставить его на усмотрение компоновщика, и в этом случае компоновщик может указать абсолютный адрес функции, который будет похож на вызов # 0xD00D.
То же самое относится к нагрузкам и хранилищам, некоторые наборы команд имеют относительный ближний и дальний компьютер, некоторые имеют абсолютный адрес и т. Д. И вы можете не выбирать, вы можете просто сказать
mov bob,r1
и ассемблерЛибо компоновщик, либо их комбинация позаботятся обо всем остальном.
Обратите внимание, что для некоторых наборов команд ассемблер и компоновщик могут происходить одновременно в одной программе.В наши дни мы привыкли к модели компиляции с объектами, а затем связываем объекты, но не все ассемблеры следуют этой модели.
В некоторых других случаях язык ассемблера может иметь несколько ярлыков:
hang: b hang
b .
b 2f
1:
b 1b
b 1f
1:
b 1b
2:
Значение hang: b hang имеет смысл, переход к метке с именем hang.По сути, это ветвь для себя.И как следует из названия, это бесконечный цикл.Но для этого языка ассемблера b.означает переход к себе, бесконечный цикл, но мне не нужно было изобретать ярлык, печатать его и переходить к нему.Другой ярлык использует числа b 1b означает переход к 1 назад, ассемблер ищет метку № 1 позади или над инструкцией.B 1f, который не является ветвью для себя, означает ветвь 1 вперед, это совершенно правильный код для этого ассемблера.Он будет смотреть вперед или ниже строки кода для метки № 1: и вы можете повторно использовать цифру 1 как сумасшедший в своей программе на ассемблере для этого ассемблера, что избавляет от необходимости изобретать имена меток для простых коротких ветвей.Второй b 1b ответвляется на второй 1. и является ответвлением для себя.
Важно понимать, что компания, создавшая процессор, определяет набор команд, а также машинный код или коды операций или любой другой термин, который ониили вы используете для битов и байтов процессор декодирует и выполняет.Очень часто эта компания выпускает документ с языком ассемблера для этих инструкций, синтаксис.Часто эта компания выпускает программу на ассемблере для компиляции / сборки этого языка ассемблера ... с использованием этого синтаксиса.Но это не означает, что любой другой человек на планете, который решит написать ассемблер для этого набора команд, должен использовать этот синтаксис.Это очень очевидно с набором инструкций x86.Точно так же любые инструкции psuedo, такие как pop up, или синтаксис макросов, или другие сокращения, такие как b 1b, должны выполняться от одного ассемблера к другому.И очень часто это не так, вы видите это с ARM, например, универсальный символ комментария;не работает с ассемблером GNU, вы должны использовать вместо @.Ассемблер ARM использует;(обратите внимание, я пишу свой ассемблер с помощью; @, чтобы сделать его переносимым).С инструментами gnu это становится еще хуже, например, вы можете поместить в язык ассемблера такие вещи, как #define и / * comment * /, и использовать компилятор C вместо ассемблера, и это будет работать.Я предпочитаю оставаться настолько чистым, насколько это возможно для максимальной мобильности, но, естественно, вы можете использовать любые функции, которые предлагает инструмент.