Отступ для директив Nasm и макросов - PullRequest
2 голосов
/ 18 марта 2019

В общепринятом синтаксисе носа инструкции имеют отступ относительно меток, например:

.top:
    dec eax
    jnz .top

Как насчет директив сборки и макросов, таких как %rep? Должно ли это быть как:

.top:
    %rep 10
    dec eax
    %endrep
    jnz .top

или

.top:
%rep 10
    dec eax
%endrep
    jnz .top

или, возможно, даже что-то еще, где сами директивы подразумевают дополнительный уровень отступа - но это будет применимо только к директивам "scoped" с открытыми закрытыми частями, таким как %rep и %endrep, а не к автономным или не вложенные.

.top:
    %rep 10
        dec eax
    %endrep
    jnz .top

Или что-то еще?

Ответы [ 2 ]

1 голос
/ 18 марта 2019

Я хотел бы взять реплику из стиля препроцессора C здесь , а отступы от директив препроцессора NASM до конца налево.(Или при вложении %if и других директив, влияющих на блок, с отступами в 2 пробела, поэтому даже вложенный %if обычно обычно начинается слева от столбца, где начинается мнемоника инструкций).

%rep / %endrep Директивы препроцессора влияют на мнемонику команд, которая встречается между ними, поэтому вы определенно хотите, чтобы они выделялись, а не смешивались и терялись в окружающих инструкциях.Когда вы видите одно, вы хотите иметь возможность визуально определить другое почти мгновенно, а не сканировать столбец мнемоники вверх или вниз в поисках первого совпадения.Особенно, если есть какая-то вложенность или другая хитрость препроцессора.

Обычно вы используете %rep только для блоков из нескольких инструкций или данных;в противном случае вы бы использовали time 10 dec eax.(Или вы используете %assign внутри %rep для создания блока, подобного dec r10d / dec r11d / dec r12d / ...). Поэтому реальные варианты использования не будут такими простыми, как в этом примере, исоответствие %endrep / %rep будет дальше, чем на 2 строки.

Если у вас есть сочетание меток и директив %if / %rep, их будет сложнее увидеть.Вы не хотите, чтобы %rep загромождала и крайний левый столбец.

Предложение Майкла Петча о дополнительном отступлении от инструкций, которые следует повторить, является хорошим.Они все равно особенные, и важно, чтобы читатели это заметили.Но они похожи на инструкции в том смысле, что они расширяются до блока инструкций, поэтому запуск %rep в столбце инструкций имеет большой смысл, а отступ в вложенном блоке позволяет легко найти начало / конец этого блока.

%if USE_SIMPLE_LOOP
.top:
    %rep 10
        imul     ecx, edx
        dec      edx
    %endrep
    sub      eax, 10
    jg      .top

Обратите внимание, что я отступил от своих операндов дальше, оставив место для мнемоники длиннее 3 символов, не сделав столбец операнда рваным.

Я намеренно отступил на целевую ветвь на 1 столбец меньше, чем другие операнды, что делает его немного выделяющимся, не будучи безобразным.Особенно, когда целью является локальная метка, которая начинается с .

Но в зависимости от варианта использования для %rep, может показаться, что лучше оставить инструкции с отступом к обычному столбцу и использовать столбец между меткамии инструкции для %rep.

%if  USE_SIMPLE_LOOP
.top:                               ; could indent the label by a column or two inside %if
  %rep 10                           ;  unroll 
    imul     ecx, edx
  %endrep
    sub      eax, 10
    jg      .top
%endif

1 голос
/ 18 марта 2019

Традиционно ассемблерный код записывался в виде четырех столбцов.Столбцы были:

  1. метка
  2. мнемоника
  3. операнд
  4. комментарий

Традиционные ассемблеры, начиная с перфорированныхкарточки распознавали значение каждого слова по тому, в каком столбце оно появилось.Современные ассемблеры используют более сложные парсеры, что позволяет программам на ассемблере иметь произвольную разметку формы.Тем не менее, для удобочитаемости стоит придерживаться традиционной компоновки.

Как видите, во втором столбце написано «мнемоника». Это указывает как на директивы ассемблера, так и на инструкции.Таким образом, чтобы ответить на ваш вопрос, директива идет в том же столбце, что и другие инструкции.Я рекомендую выделить брекеты, как в вашем примере %rep ... %endrep, с помощью пустых строк:

.top:   %rep 10
        dec eax
        %endrep

        jnz .top
...