Какова была первоначальная причина дизайна синтаксиса сборки AT & T?

При использовании инструкций по сборке на x86 или amd64 программист может использовать компилятор "Intel" (т.е. nasm) или "AT & T" (т.е. gas компилятор). Синтаксис "Intel" более популярен в Windows, но "AT & T" более популярен в UNIX-подобных системах.

Но и руководства Intel и AMD, поэтому руководства, созданные создателями чипа, используют синтаксис "Intel" .

Мне интересно, какова была оригинальная идея дизайна синтаксиса AT & T? Какова была польза для плавания от нотации, используемой создателями процессора?

Ответ 1

Расширение ответа Johan: UNIX долгое время разрабатывался на PDP-11, 16-битном компьютере от DEC, который имел довольно простой набор команд. Почти каждая команда имеет два операнда, каждый из которых может иметь один из следующих восьми режимов адресации, как показано на языке ассемблера MACRO 16:

0n  Rn        register
1n  (Rn)      deferred
2n  (Rn)+     autoincrement
3n  @(Rn)+    autoincrement deferred
4n  -(Rn)     autodecrement
5n  @-(Rn)    autodecrement deferred
6n  X(Rn)     index
7n  @X(Rn)    index deferred

Непосредственные адреса и прямые адреса могут быть использованы путем умного повторного использования некоторых режимов адресации на R7, счетчик программ:

27  #imm      immediate
37  @#imm     absolute
67  addr      relative
77  @addr     relative deferred

В качестве драйвера UNIX tty в качестве управляющих символов использовались @ и #, вместо # и * для @ вместо @ была заменена $.

Этот синтаксис был адаптирован к процессору 8086 и его режимам адресации:

mr0 X(bx,si)  bx + si indexed
mr1 X(bx,di)  bx + di indexed
mr2 X(bp,si)  bp + si indexed
mr3 X(bp,di)  bp + di indexed
mr4 X(si)     si indexed
mr5 X(di)     di indexed
mr6 X(bp)     bp indexed
mr7 X(bx)     bx indexed
3rR R         register
0r6 addr      direct

Где m равно 0, если индекс отсутствует, m равно 1, если есть однобайтовый индекс, m равно 2, если есть двухбайтовый индекс, а m равно 3, если вместо этого операнда памяти используется регистр. Если существуют два операнда, другой операнд всегда является регистром и закодирован в цифре r. В противном случае r кодирует еще три бита кода операции.

В этой схеме адресации невозможны немедленные действия, все инструкции, которые принимают немедленно, кодируют этот факт в своем коде операции. Immediates пишется $imm точно так же, как в синтаксисе PDP-11.

Инструкции по прыжкам и вызовам преследуют цель. Для косвенного перехода цель имеет префикс * (например, jump *%eax). Это необходимо, чтобы отличить jump foo (перейти к foo) от jump *foo (перейти к адресу, сохраненному в местоположении foo). Они могли бы спроектировать прямые прыжки, чтобы иметь свои операнды с префиксом $, но из-за редкости косвенных прыжков это синтаксическое исключение обеспечивает приятное удобство.

Этот синтаксис был расширен для указания префикса сегмента с использованием двоеточия:

seg:addr

Когда был введен 80386, эта схема была адаптирована к новым режимам SIB-адресации с использованием четырехэтапного режима общей адресации:

disp(base,index,scale)

где disp - это смещение, базой является базовый регистр, index индексный регистр и scale равен 1, 2, 4 или 8, чтобы масштабировать регистр индекса на одну из этих сумм. Это соответствует синтаксису Intel:

[disp+base+index*scale]

Еще одна замечательная особенность PDP-11 заключается в том, что большинство инструкций доступны в байте и варианте слова. Какой из них вы используете, указывается суффиксом b или w для кода операции, который напрямую переключает первый бит кода операции:

 010001   movw r0,r1
 110001   movb r0,r1

это также было адаптировано для синтаксиса AT & T, поскольку большинство команд 8086 действительно доступны также в режиме байта и в режиме слова. Позже в 80386 и AMD K6 были введены 32-битные команды (суффикс l для long) и 64-битные команды (суффикс q для квадроцикла).

И последнее, но не менее важное: изначально соглашение состояло в том, чтобы префикс символов языка C с подчеркиванием (как это делается в Windows), поэтому вы можете отличить функцию C с именем ax от регистра ax. Когда SUN Microsystems разработали бинарный формат ELF, они решили избавиться от этого украшения. Поскольку нет способа отличить прямой адрес от регистра в противном случае, они добавили префикс % к каждому регистру:

mov direct,%eax # move memory at direct to %eax

И вот как мы получили синтаксис AT & T.

Ответ 2

Язык ассемблера определяется ассемблером, программным обеспечением, которое анализирует язык ассемблера. Единственным "стандартом" является машинный код, который должен соответствовать процессору, но если вы возьмете 100 программистов и дадите им стандартный код машины (без подсказок на языке ассемблера), вы получите где-то от 1 до 100 различных языков ассемблера, Что все будет отлично работать для всех случаев использования этого процессора (baremetal, операционная система, работа приложения), если они делают полный инструмент, который вписывается в инструментальную цепочку.

Именно в интересах создателя набора команд, машинного кода, создать как документ, описывающий набор команд, так и ассемблер, первый инструмент, который вам нужен. Они могут заключить контракт или сделать это в доме, в любом случае это не имеет значения, но наличие ассемблера с синтаксисом и документа для машинного кода, который использует синтаксис ассемблера для соединения точек между ними, предоставит кому-либо возможно заинтересовался этим процессором отправной точкой. Как и в случае с Intel и 8086/88. Но это не означает, что masm и tasm полностью совместимы с ассемблером intels. Даже если синтаксис для каждой команды согласован, синтаксис каждой команды является лишь частью языка ассемблера, существует множество синтаксиса, не относящихся к инструкциям, директивам, макроязыку и т.д. И это было от конца DOS в мире. конец UNIX и, таким образом, AT & T. В то время gnu-люди были unix-концом мира, поэтому совершенно понятно, что они использовали синтаксис AT & T или производную, поскольку они, как правило, испортили язык ассемблера во время порта. Возможно, есть исключение.

nasm, а некоторые другие - попытка продолжить синтаксис masm, так как masm - это инструмент Microsoft с закрытым исходным кодом (как и tasm, и что-то было с Borland C, если это тоже не было). Теперь они могут быть открытыми, но не нужно, проще писать с нуля, чем пытаться перенести этот код, я предполагаю, что он будет построен с использованием современного компилятора, и nasm уже существует.

Почему возникает вопрос, как спросить меня, почему вы выбрали пару носков, которые вы выбрали сегодня утром или в какой-то конкретный день. Ваши носки, возможно, не имеют большого влияния на остальной мир, но вопрос в равной степени не имеет значения и/или неосуществим. Ответ частично отчасти просит попросить 100 программистов сделать ассемблер для определения того же машинного кода. некоторые из этих программистов могут быть испытаны на языке ассемблера и могут выбрать, чтобы создать язык ассемблера в образе того, который они использовали до того, что означает, что некоторые из них сделают один, который выглядит очень похожим друг на друга. Но тот, который они использовали раньше, может быть другим, поэтому были бы группы этих похожих, но все же разных. Тогда в Let say 30 лет спросите каждого из этих 100 человек, почему вопрос... если они все еще живы... Как и спрашивать меня, почему вы решили объявить переменную в программе, которую вы написали 30 лет назад так, как вы это делали он.