Зачем мне использовать NASM вместо GNU Assembler (GAS)?

Зачем мне использовать NASM вместо GNU Assembler (GAS), если GAS поддерживает несколько архитектур, тогда как NASM поддерживает исключительно архитектуру x86? Я знаю, что есть синтаксические различия, но меня это не слишком беспокоит.

Это всего лишь дело вкуса. Но реальный вопрос заключается в том, зачем использовать какой-либо ассемблер, если компиляторы (например, GCC...) могут встраивать оператор asm? В 2020 году обычно генерируется код на ассемблере. Вы можете скомпилировать некоторые foo.c с gcc -fverbose-asm -O2 -S foo.c и посмотреть на сгенерированный foo.s

Basile Starynkevitch 24.12.2020 10:31

@BasileStarynkevitch Я изучаю ассемблер

Serket 24.12.2020 10:32

Мне любопытно: зачем ты изучаешь ассемблер? См. также Руководство по сборке Linux и, возможно, отправьте мне письмо по адресу [email protected]

Basile Starynkevitch 24.12.2020 10:36

@BasileStarynkevitch Итак, вы хотите, чтобы я отправил вам по электронной почте причины, по которым я заинтересован в ассемблере / ly?

Serket 24.12.2020 10:38

Да, потому что в 2020 году это 95% времени потери времени вашего разработчика. Более эффективно использовать операторы asm с GCC, например. чтобы смешать несколько операторов asm в вашем коде C

Basile Starynkevitch 24.12.2020 10:39

@BasileStarynkevitch Я могу рассказать вам причины прямо здесь: я хочу понять, как работает процессор, более подробно. Я хочу понять, как работает память. Я хотел бы прочитать исходный код ядра Linux и заинтересован в взломе памяти.

Serket 24.12.2020 10:41

Но ядро ​​Linux (или musl-libc , или GNU libc...) написано в основном на C

Basile Starynkevitch 24.12.2020 10:42

@BasileStarynkevitch, в нем все еще есть код на ассемблере. Я также заинтересован в написании собственной ОС и программировании встроенных систем.

Serket 24.12.2020 10:44

@BasileStarynkevitch плюс, это интересно

Serket 24.12.2020 10:44

Тогда смотрите также OSDEV .... Для встраиваемых систем рассмотрите Arduino

Basile Starynkevitch 24.12.2020 10:44

@BasileStarynkevitch: понимание языка ассемблера по-прежнему полезно для понимания производительности и архитектуры ЦП (проектные решения, которые принимают разработчики ЦП). На самом деле я не трачу время на написание производственного кода на ассемблере, только микробенчмарки, но я довольно хорошо знаю ассемблер и процессоры. (Ради развлечения и прибыли.) Я не вижу смысла в написании 16-битного загрузчика или программы для DOS, если они будут просто работать с эмулируемым устаревшим оборудованием, но я получил свой опыт работы с Atari ST еще в конце прошлого века. 90-х, прежде чем получить ПК для запуска Linux.

Peter Cordes 24.12.2020 10:45

@BasileStarynkevitch блин... большое спасибо!!! я искал что-то подобное целую вечность.

Serket 24.12.2020 10:45

@PeterCordes: Я тоже. Но в последний раз я писал код на ассемблере в прошлом веке.

Basile Starynkevitch 24.12.2020 10:46

@BasileStarynkevitch: обычно я пишу asm в голове, а затем набираю встроенные функции C или C++ SIMD, чтобы заставить компилятор выдавать что-то близкое к тому, о чем я думал. Иногда компиляторы усложняют задачу заставить их генерировать asm настолько эффективно, насколько мне хотелось бы, тогда я либо отправляю отчёт о пропущенной ошибке оптимизации, либо добавляю его в список TODO, к которому нужно вернуться...

Peter Cordes 24.12.2020 10:50

@Serket: добавлено еще несколько пунктов в пользу NASM, особенно %rep / times важны для удобного экспериментирования / микробенчмаркинга.

Peter Cordes 24.12.2020 11:42

Писать ассемблер очень весело! Я действительно могу порекомендовать это.

fuz 24.12.2020 13:27

Я думаю, что лучше изолировать сборку от кода C и использовать встроенную сборку только там, где это необходимо, поскольку компиляторы иногда могут поиграть с вашей сборкой и испортить ее.

Expolarity 24.12.2020 14:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
17
1 962
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ASM по своей сути не является переносимым. Только директивы GAS одинаковы для других ISA (не инструкции и даже не символы комментария), и любой данный исходный файл asm будет для одного ISA. Сама по себе ГАС с поддержкой множественных целей не особо актуальна, надо еще другие машины учить. (Что несложно понять хотя бы основы, когда вы их знаете, но различия в синтаксисе директив, как правило, еще проще). Некоторые другие ассемблеры для других ISA используют псевдоинструкции данных в стиле NASM db и dd, другие используют .byte и .long в стиле Unix, например GAS (или являются GAS). Но к этому очень легко приспособиться.

GAS был впервые разработан для сборки выходных данных компилятора; поэтому его сообщения об ошибках не всегда удобны для человека. (С точки зрения ясности о том, что именно ему не нравится в строке). NASM имеет тенденцию быть лучше (но ни в коем случае не идеальным), и современный GAS в целом тоже неплох; некоторые крупные проекты (такие как glibc и Linux) имеют исходные файлы GAS, написанные от руки, поэтому они, безусловно, используются людьми.

В NASM есть язык макросов (https://www.nasm.us/doc/nasmdoc4.html ), который в некоторых отношениях проще использовать для сложных вещей, чем макросы GAS .macro. (Хотя макросы CPP часто используются с GAS).

Для микробенчмаркинга (одна из немногих причин играть с asm вручную в наши дни) в NASM есть функции, которые я не знаю, как легко сделать в GAS: times повторять одну строку. %rep повторять блок тоже полезно. GAS .rept может это сделать, но если вы хотите изменить блок (например, развернуть и сделать [rdi+0] / [rdi+4] / ...), NASM лучше. В GAS вы можете использовать рекурсивный макрос, который вызывает сам себя с меньшим аргументом, но NASM позволяет %assign реализовать счетчик внутри %rep.

    times 10  imul eax,eax        ; repeat this line 10 times

 %rep 10                       ; repeat this block 10 times
    add  eax, ecx
    add  ecx, eax
 %endrep

NASM имеет очень удобный синтаксис для многосимвольных констант в виде чисел, например. mov rax, 'abcdefgh' / push rax приводит к этим 8 символам ASCII в стеке в исходном порядке. GAS не может сделать ничего подобного; вам нужно использовать необработанные числа или что-то вроде 'h'<<56 | 'g'<<48 | ...

NASM может собрать плоский двоичный файл, не усложняя компоновщик + скрипт компоновщика. В основном актуально только для 16-битных загрузчиков, но возможно и для шеллкода.

До недавнего времени в GAS были некоторые плохие вещи, такие как add [rdi], 1234 молчаливое значение по умолчанию для размера операнда двойного слова, вместо того, чтобы предупреждать вас, что это неоднозначно для инструкций, отличных от mov. Недавний GAS исправил это; теперь это ошибка, как и в NASM. (В режиме AT&T GAS просто предупреждает, но в режиме синтаксиса Intel это ошибка.)


Синтаксис NASM на 100% согласован с [] - наличие квадратных скобок всегда означает операнд памяти, а отсутствие означает, что никогда не будет операнда памяти. (Чтобы было ясно, что я имею в виду, LEA берет операнд памяти, но не загружается из него.) Синтаксис AT&T также легко отличить ($ или нет — это разница между непосредственным или памятью), но GAS .intel_syntax noprefix зависит от того, как был объявлен символ. add eax, foobar может быть add eax, imm32 или add eax, [disp32]. Хуже того, это зависит от того, было ли foobar объявлено с equ или = до или после инструкции, которая его использует, если только вы не используете OFFSET, даже если вы позже делаете foobar = 42!!! Отличие памяти от константы в GNU как .intel_syntax.

Синтаксис Intel является основным и единственным режимом NASM, поэтому вы можете легко найти инструкции в руководствах Intel или AMD. .intel_syntax noprefix — это второстепенная функция GAS, не так хорошо задокументированная, как AT&T. Он работает прилично, за исключением вышеуказанной двусмысленности.

И иногда инструменты GNU даже в режиме синтаксиса Intel (например, objdump -d -Mintel) по-прежнему следуют замене синтаксической ошибки AT&T некоторых форм инструкций x87, таких как fdiv против fdivr. Если вы когда-нибудь захотите использовать x87, по возможности избегайте GAS. См. 9.16.17 Ошибки синтаксиса AT&T в руководстве GAS. Я думаю, что современный objdump может «сделать это правильно» сейчас, но если бы я использовал только GAS + binutils, у меня не было бы чего-то, что, как я доверял, не было бы повреждено глупыми ошибками реализации AT&T, с которыми GAS должен был быть совместим с ошибками. Совершенно не имеет значения за пределами инструкций x87, поэтому, к счастью, сейчас не имеет значения большую часть времени.

Это охватывает все это с точки зрения обзора. Я рад, что вы затронули функцию макросов NASM. Это часто упускается из виду, но очень удобно для небольших задач. Всегда поучительные ответы.

David C. Rankin 24.12.2020 11:49

Другие вопросы по теме