Подтвердить что ты не робот

Учимся читать вывод ассемблера GCC

Я подумываю о том, чтобы собрать кое-что очень рудиментарное понимание сборки. Моя текущая цель проста: VERY BASIC понимание вывода ассемблера GCC при компиляции C/С++ с помощью ключа -S для x86/x86-64.

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

Кто-нибудь знает/знает о самом сжатом вступлении к сборке, относящемся к GCC, и специально для целей чтения, и список наиболее важных инструкций, которые должны знать люди, читающие ассемблер?

4b9b3361

Ответ 1

Если вы используете gcc или clang, аргумент -masm = intel сообщает компилятору генерировать сборку с синтаксисом Intel, а не синтаксисом AT & T, а аргумент -save-temps сообщает компилятору сохранять временные файлы ( предварительно обработанный источник, сборка, несвязанный объектный файл) в каталоге GCC вызывается.

Получение поверхностного понимания сборки x86 должно быть легко со всеми ресурсами. Вот один из таких ресурсов: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html.

Вы также можете просто использовать disasm и gdb, чтобы узнать, что делает скомпилированная программа.

Ответ 2

Вы должны использовать GCC -fverbose-asm. Это заставляет компилятор выводить дополнительную информацию (в виде комментариев), которая упрощает понимание отношения кода сборки к исходному коду C/С++.

Ответ 3

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

В Intel, к счастью, коды операций несколько разумны. PowerPC не так по-моему. MIPS был моим фаворитом. Для MIPS я позаимствовал у своего ближнего справочника, а для PPC у меня была документация IBM в PDF, которая была удобна для поиска. (И для Intel, в основном, я предполагаю, а затем наблюдаю за регистрами, чтобы убедиться, что я догадываюсь правильно! Heh)

В принципе, сама сборка проста. В основном это три вещи: перемещение данных между памятью и регистрами, работа с данными в регистрах и изменение счетчика программ. Сопоставление между вашим языком выбора и сборкой потребует некоторого изучения (например, обучения распознаванию вызова виртуальных функций), и для этого очень полезен "интегрированный" источник и разборный вид (например, вы можете получить в Visual Studio).

Ответ 4

"случайно считывание сборки" lol (красиво)

Я бы начал с выполнения в gdb во время выполнения; вы лучше чувствуете, что происходит. Но тогда, возможно, это только я. он разобьет функцию для вас (disass func), тогда вы можете сделать один шаг через нее

Если вы делаете это исключительно для проверки оптимизации, не беспокойтесь.

a) компилятор делает хорошую работу

b) вы не сможете понять, что он делает в любом случае (никто не может)

Ответ 5

В отличие от языков более высокого уровня, действительно нет большой (если есть) разницы между возможностью чтения сборки и возможностью ее записи. Инструкции имеют отношение "один к одному" с кодами операций CPU - нет никакой сложности, чтобы пропустить, сохраняя при этом понимание того, что делает строка кода. (Это не похоже на язык более высокого уровня, где вы можете увидеть строку, которая говорит "print $var", и не нужно знать или заботиться о том, как она выводится на экран.)

Если вы все еще хотите изучать сборку, попробуйте книгу "Шаг за шагом: программирование в Linux" Джеффом Дантеманом.

Ответ 6

Я уверен, что есть вводные книги и веб-сайты, но довольно эффективный способ обучения - на самом деле получить ссылки на Intel, а затем попытаться сделать простые вещи (например, целую математику и логическую логику) в вашем любимом высокого уровня, а затем посмотрите, что представляет собой двоичный код.