Не то, чтобы мне часто приходилось что-то там дизассемблировать. Но время от времени возникает желание посмотреть, в какой ассемблерный код превратился твой код на C. Для решения этой задачи зачастую хватает objdump, но только если ты заранее знаешь, где и что именно ищешь. Для более сложных случаев возникает потребность в чем-то вроде IDA Pro, да вот только стоит эта IDA Pro как вне себя (минимум 589$). К счастью, есть не менее функциональная альтернатива с вменяемой стоимостью (99$) в лице дизассемблера Hopper.

Простите, у вас не найдется минутки поговорить о спасителе нашем, ассемблере? В прошлой статье мы написали наше первое hello world приложение на асме, научились его компилировать и отлаживать, а также узнали, как делать системные вызовы в Linux. Сегодня же мы познакомимся непосредственно с ассемблерными инструкциями, понятием регистров, стека и вот этого всего. Ассемблеры для архитектур x86 (a.k.a i386) и x64 (a.k.a amd64) очень похожи, в связи с чем нет смысла рассматривать их в отдельных статьях. Притом акцент я постараюсь делать на x64, попутно отмечая отличия от x86, если они есть. Далее предполагается, что вы уже знаете, например, чем стек отличается от кучи, и объяснять такие вещи не требуется.

Сегодня мы поговорим о программировании на ассемблере. Вопрос «зачем кому-то в третьем тысячелетии может прийти в голову писать что-то на ассемблере» раскрыт в заметке Зачем нужно знать всякие низкоуровневые вещи, поэтому здесь мы к нему возвращаться не будем. Отмечу, что в рамках поста мы сосредоточимся на вопросе компиляции и отладки программ на ассемблере. Сам же язык ассемблера заслуживает отдельного большого поста, а то и серии постов.