Чтобы научиться сборке - я должен начать с 32-битной или 64-битной?

Очень хочу выучить сборку. Я неплохо разбираюсь в c / c ++, но хочу лучше понимать, что происходит на более низком уровне.

Я понимаю, что вопросы, связанные со сборкой, задавались и раньше, но я просто ищу какое-то направление, которое подходит для моей ситуации:

Я использую Windows 7 и не понимаю, как мне начать работу со сборкой. Мне нужно начинать с x64, потому что я использую Windows 7? Некоторые люди говорят: «Сначала начните с 32-битной версии» - как мне это сделать? Какое отношение имеет моя операционная система к моей способности писать сборку для 32 или 64 битов? На самом деле, что означает «n-битная» сборка, где n - число ??


Редактировать:

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

Примечание. По мере обучения я решил сосредоточиться на программировании с помощью masm32. Поэтому большинство из приведенных ниже ресурсов посвящено именно этому.

  • x86 tag wiki (руководства для начинающих, справочные руководства, документация по ABI и т. д.)
  • www.masm32.com
  • WikiBook по сборке X86
  • WikiBook по разборке X86 (отлично подходит для понимания некоторых соглашений и основ того, как код более высокого уровня преобразуется в сборку )
  • WinAsm IDE (отлично работает с masm32)
  • Введение: сборка для Windows (все примеры кода предназначены для masm32)
  • Список прерываний
  • Руководство по сборке (отлично помогает понять основные концепции)
  • Руководство по сборке x86
  • Ресурсы по оптимизации программного обеспечения Agner Fog, включая полезные сведения о соглашениях о вызовах на разных платформах (Windows и Linux / OS X ), а также множество примеров того, как эффективно делать то или иное дело. Не очень подходит для новичков, но отлично подходит для читателей среднего и продвинутого уровней.

    (У него также есть подробная информация о производительности для каждой инструкции для процессоров Intel и AMD, что отлично подходит для серьезной микрооптимизации производительности. Некоторые новички могут захотеть взглянуть на некоторые из них, чтобы начать думать о том, как работают процессоры, и почему вы можете что-то сделать. путь вместо другого.)


person Community    schedule 28.02.2010    source источник
comment
Рассмотрите возможность программирования с нуля   -  person    schedule 01.03.2010
comment
Удачи, чувак. Написание ассемблера - это настоящая тягость. Не пытаюсь отговорить это, но, черт возьми, это довольно затея   -  person HumbleWebDev    schedule 29.08.2017


Ответы (5)


Когда люди обращаются к 32-bit и 64-bit сборке, они говорят о том, какой набор инструкций вы будете использовать - их также иногда называют Ia32 и x64 в случае Intel, о котором, я полагаю, вы спрашиваете. В 64-битном случае происходит гораздо больше, поэтому начать с 32-битного, вероятно, будет неплохо; вам просто нужно убедиться, что вы собираете свою программу с помощью 32-битного ассемблера в 32-битный двоичный файл. Windows все равно будет знать, как его запустить.

Что я действительно рекомендую для начала работы со сборкой, так это что-то с более простым набором инструкций, с которым можно было бы справиться. Изучите сборку MIPS - _ 5_ Симулятор великолепен и прост в использовании. Если вы действительно хотите погрузиться прямо в мир сборки Intel, напишите себе небольшую программу на C, которая будет вызывать ваши процедуры сборки за вас; выполнение всех настроек и демонтажа «настоящей программы» - это большой беспорядок, и вы даже не сможете начать с этого. Так что просто напишите оболочку C с main() в ней, скомпилируйте и свяжите ее с объектными файлами, которые вы получите при написании кода сборки.

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

Чтобы получить начал.

person Carl Norum    schedule 28.02.2010
comment
Это полезно, спасибо. Разница в наборе команд имеет смысл ... это единственная разница? Например, есть ли разница в способе работы 32-битной программы по сравнению с 64-битной? Если нет, то почему они называются 32-битными / 64-битными, в отличие, например, от «набора инструкций A» и «набора инструкций B»? - person Cam; 28.02.2010
comment
@incrediman, набор инструкций - довольно большая разница. У наборов инструкций действительно разные имена, но люди просто сокращают 32-битные / 64-битные версии. Кроме того, существуют разные соглашения о вызовах (ABI) между двумя наборами инструкций и даже между двумя конкурирующими 64-битными ABI. - person Carl Norum; 28.02.2010
comment
На данный момент мы будем просто выполнять 32-битное кодирование, поэтому внутренние регистры в ЦП для нас будут 32-битными. Каждый бит может хранить 1 или 0. (friedspace.com/assembly/cpuregs1.php) ... Это дополнительная разница между 32 и 64 битным asm? Если нет, то что это предложение пытается сказать? Спасибо! - person Cam; 28.02.2010
comment
@incrediman, да. 64-битная архитектура имеет 64-битные регистры (и адресацию памяти), а 32-битная архитектура имеет 32-битные регистры. Это одна из причин, по которой люди используют имена 64/32, чтобы различать их. - person Carl Norum; 28.02.2010
comment
Спасибо за терпение / ответы! Хорошо - на этом этапе я загрузил masm32 и успешно создал консольное приложение hello world, используя простой пример кода и включаемый файл. Я загрузил masm32 здесь: masm32.com, так что он у меня работает. это хорошее место для начала? - person Cam; 28.02.2010
comment
@Carl, x64 должно быть x86-64, чтобы избежать путаницы с несовместимыми 64-разрядными процессорами Intel серии IA64 (Itanium). - person mctylr; 01.03.2010
comment
Обязательно подумайте о приобретении эмулятора микроконтроллера и изучении сборки для него. Сборка в значительной степени мертва для ПК (большинство компиляторов могут создавать лучший код ASM на более высоком языке, чем программисты могли бы вручную), но он по-прежнему очень силен для микроконтроллеров, и различные интересные проекты, которые вы могли бы реализовать с ними, действительно стоят затраченных усилий. Кроме того, вы можете писать без ОС, которая при сборке чаще мешает вам, чем помогает. - person SF.; 01.03.2010
comment
Спасибо, SF, это хорошая идея. На самом деле, хотя у меня есть несколько микроконтроллеров, я, вероятно, выучу для них сборку, что было бы довольно круто. Кроме того, я не пытаюсь делать полезное программное обеспечение на сборке для моего ПК с Windows 7 :) ... Я в основном изучаю это, чтобы начать узнавать, что происходит за моим высокоуровневым кодом. - person Cam; 07.03.2010
comment
Я думаю, что я бы не согласился с этими парнями и выбрал 64-битную - 64-битную сборку в два раза больше регистров, что дает больше возможностей для обучения. - person Joel; 17.05.2010

Я начал писать ассемблер в 1977 году, пройдя длинный путь: сначала изучил базовые операции (and, or, xor, not) и восьмеричную математику, прежде чем писать программы для DEC PDP-8 / E с OS / 8 и 8k памяти. Это было в 1977 году.

С тех пор я открыл для себя несколько приемов изучения сборки для незнакомых мне архитектур. Было несколько: 8080/8085 / Z80, x86, 68000, VAX, 360, HC12, PowerPC и V850. Я редко пишу автономные программы, обычно это функции, связанные с остальной частью системы, которая обычно написана на C.

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

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

Полезно узнать (помимо упомянутой ранее обработки стека), как компилятор генерирует машинный код с учетом определенной языковой конструкции высокого уровня. Одна из таких последовательностей - это то, как индексированные массивы / структуры преобразуются в указатели. Другой - это базовая последовательность машинного кода для циклов.

Так что же такое «сырой отладчик»? Для меня это отладчик, который является частью простого пакета разработки и не пытается защитить меня от оборудования, такого как отладчик (-ы) Visual. В нем я могу легко переключаться между отладкой исходного кода и отладки сборки. Он также быстро запускается из среды разработки. У него нет трех тысяч функций, скорее всего, тридцати, и вы будете использовать их 99,9% времени. Пакет разработки обычно является частью установщика, где вы щелкаете один раз для утверждения лицензии, один раз для утверждения настройки по умолчанию (разве вам не нравится, когда кто-то подумал и сделал эту работу за вас?) И последний раз для установки .

У меня есть одна любимая простая среда разработки для x86-32 (IA-32), и это OpenWatcom. Вы можете найти его на openwatcom.org.

Я новичок в x86-64 (AMD64), но переход кажется простым (как при переходе с x86-16 на x86-32) с некоторыми дополнительными уловками, такими как дополнительные регистры от r8 до r15 и что основные регистры 64-битные. широкий. Я совсем недавно наткнулся на среду разработки для XP / 64, Vista / 64 и 7/64 (вероятно, также работает для серверных ОС), и она называется Pelles C (pellesc.org). Он написан и поддерживается неким Пелле Ориниусом из Швеции, и по тем нескольким часам, которые я провел с ним, я могу сказать, что ему суждено стать моим фаворитом для x86-64. Я пробовал пакеты Visual Express (они устанавливают так много мусора - вы знаете, сколько деинсталляций вам нужно сделать потом? Более 20), а также попытался получить gcc из одного места для работы с IDE (eclipse или что-то еще ) От другого.

Как только вы зашли так далеко и натолкнетесь на новую архитектуру, вы сможете потратить час или два на просмотр сгенерированного списка, а после этого в значительной степени узнать, на какую другую архитектуру он похож. Если конструкции индекса и цикла кажутся странными, вы можете просмотреть исходный код, их генерирующий, а также, возможно, уровень оптимизации компилятора.

Думаю, я должен предупредить вас, что как только вы освоитесь, вы заметите, что за столиками рядом, у кофемашины, на собраниях, на форумах и во многих других местах будут люди, которые будут ждать вас, чтобы презирать вас, высмеивать вы, бросайте вам неполные цитаты и даете неосведомленные / некомпетентные советы из-за вашего интереса к сборке. Почему они это делают, я не знаю. Возможно, они сами являются неудавшимися программистами на ассемблере, возможно, они знают только объектно-ориентированное программирование (C ++, C # и Java) и просто не имеют ни малейшего представления о том, что такое ассемблер. Возможно, кто-то, кого они «знают» (или кого знает их друг), кто «действительно хорош», возможно, читал что-то на форуме или слышал что-то на конференции и, следовательно, может сказать абсолютную правду о том, почему сборка - это пустая трата времени. время. Их здесь много, в stackoverflow.

person Community    schedule 16.02.2011
comment
Отличный ответ (спасибо, что добавили его, несмотря на возраст вопроса), но вам не нужно было делать это вики-сообществом - вы заслуживаете репутации! :) - person Cam; 16.02.2011
comment
Спасибо, Кэм. Я чувствовал, что вопрос требует большего ... как на практике! - person Olof Forshell; 16.02.2011

Получите IDA pro. Это колени для работы со сборкой.

Лично я не вижу большой разницы между 32-битной и 64-битной. Дело не в битах, а в наборе команд. Когда вы говорите о сборке, вы говорите о наборах инструкций. Возможно, они подразумевают, что лучше учиться на 32-битном наборе команд. Однако, если это ваша цель, я предлагаю книги Дональда Кнута по алгоритмам - они учат алгоритмы в терминах 7-битной сборки набора команд: D

Что касается проблем с переносимостью, я предлагаю вам вместо встроенной сборки научиться использовать встроенные функции компилятора - это будет лучшая оптимизация для невстроенных оптимизаций. : D

person Hassan Syed    schedule 28.02.2010
comment
Из того, что я читаю, это дизассемблер ... так что на самом деле писать / кодировать какой-то код на ассемблере невозможно, верно? Если так, то это только половина ответа. - person Jürgen A. Erhard; 28.02.2010
comment
Работа со сборкой в ​​наши дни (даже во встроенных системах) сводится к внесению корректировок в код, сгенерированный компилятором C / C ++. IDA делает эту работу максимально безболезненной. - person Hassan Syed; 28.02.2010
comment
Может быть, но он все равно не ответил на мой первоначальный вопрос так хорошо :) - person Cam; 28.02.2010
comment
@Hassan, что, если мне нужно написать код, который запускается до того, как существует среда выполнения C / C ++? - person Carl Norum; 28.02.2010
comment
@Hassan Да, правда. Может я был немного резковат ... извините! - person Cam; 28.02.2010
comment
@carl, ты знаешь ответ на этот бессмысленный вопрос, как и я, ты пишешь ассемблерный / машинный код. - person Hassan Syed; 28.02.2010
comment
@Hassan, вы только что сказали четырьмя комментариями выше, что работа со сборкой означает внесение изменений в код, сгенерированный компилятором; Я просто пытался представить контрпример. - person Carl Norum; 28.02.2010

но хотите лучше понять, что происходит на более низком уровне

Если вы действительно хотите знать все, что происходит на более низком уровне в процессорах / системах x86 / x64, я бы действительно рекомендовал начать с основ, то есть с кода реального режима 286/386. Например, в 16-битном коде вы вынуждены использовать сегментацию памяти, что является важной концепцией для понимания. Сегодняшние 32-битные и 64-битные операционные системы по-прежнему запускаются в реальном режиме, а затем переключаются между соответствующими режимами.

Но если вас интересует разработка приложений / алгоритмов, возможно, вам не захочется изучать все низкоуровневые ОС. Вместо этого вы можете сразу начать с кода x86 / x64, в зависимости от вашей платформы. Обратите внимание, что 32-битный код также будет работать в 64-битной Windows, но не наоборот.

person AndiDog    schedule 28.02.2010
comment
Время загрузки - не единственный низкоуровневый способ взаимодействия с системой; Я считаю, что написание нативной сборки для программ ОС - хороший способ начать. Написание и отладка загрузочных систем не для слабонервных. - person Carl Norum; 28.02.2010
comment
Понимание 16-битных сегментов примерно так же полезно, как и изучение римских цифр. Что касается запуска в реальном режиме для начальной загрузки вашей собственной ОС, это потребует нескольких лет изучения, если только он не будет печататься. BIOS передал мне эти значения регистров на экране xxxx xxxx. Низкоуровневые вещи, такие как чтение / запись аппаратных портов в драйверы устройств, были бы хорошим применением для ассемблерного кода, даже если вы не гений asm. - person Arthur Kalliokoski; 01.03.2010
comment
Сегментация в длинном режиме x86-64 в основном рудиментарна. Для большинства сегментных регистров база фиксирована на 0, поэтому единственным вариантом является плоская память (как и все основные операционные системы, использующие 32-разрядный режим). Изучая 16-битную сегментацию после, вы поймете, что более простая плоская модель памяти может помочь понять, как fs или gs используются для локального хранилища потоков в современных системах. Но я бы не рекомендовал пытаться сначала изучить это. Даже внутренне современные процессоры имеют особый случай, когда сегментная база = 0, и в противном случае имеют более высокую задержку для нагрузок. Так что даже внутри компании сегментации не происходит. - person Peter Cordes; 13.07.2017
comment
Если вы в основном хотите использовать asm для того, чтобы компилятор хорошо справлялся с кодом пользовательского пространства (например, заметьте, что он выполнил плохую работу, и измените источник, чтобы улучшить выпуск asm), вам не нужно ничего знать о сегментация для подавляющего большинства случаев. Сегменты в современной x86 - это то, как 64-разрядная ОС запускает 64- или 32-разрядные процессы (разные дескрипторы CS) и как они выполняют TLS. (Разная fs база для каждого потока). Пока вы не будете готовы этому научиться, игнорируйте сегменты. - person Peter Cordes; 13.07.2017

Начало программирования на C (а не на C ++ или C #) поможет вам получить базовое представление о том, что необходимо «сделать все самостоятельно», например о регистрах, кадрах стека и обработке данных. Я получил степень магистра по информатике, и одна из моих любимых тем - сборка компиляторов (да, yacc и lex!), Которая действительно помогла мне понять все языки высокого уровня на глубоком интимном уровне. Я до сих пор ценю те моменты, когда определяю свой собственный язык и компилирую его в конструкции низкого уровня. Действительно, я разработал объектно-ориентированный язык, который будет выполняться на виртуальном процессоре.

Итак: нет никаких ярлыков для изучения ассемблера. Это может быть утомительно. Но очень сытно.

person Community    schedule 23.06.2019