Что вам не хватает, так это то, что часть кода операции закодирована в байте ModR / M. Обычно байт ModR / M кодирует два операнда. Первый операнд является регистром или операндом памяти, как указано в метках строк слева от таблицы, в то время как второй операнд является регистром, заданным заголовками столбцов в верхней части таблицы. Для инструкций только с одним операндом, таких как инструкция CALL, второй операнд вместо этого используется для предоставления дополнительных битов кода операции.
Если вы посмотрите документацию для инструкции CALL, то увидите, что код операции для инструкции "Call Near, абсолютно косвенный адрес, указанный в r / m32" указан как FF /2
. /2
указывает, что дополнительные биты кода операции в байте ModR / M имеют значение 2 в этой инструкции. Если вы затем посмотрите на заголовки столбцов «(в десятичном формате) / цифра (код операции)», то увидите, что число 2 появляется в начале столбца. Если вы посмотрите вниз на этот столбец, вы увидите 55
в строке, помеченной «[EBP] + disp8».
Это описано в Руководстве Intel для разработчиков ПО, том 2, в разделе 3.1.1.1 Столбец кода операции вСводная таблица инструкций (инструкции без префикса VEX):
- / цифра - цифра от 0 до 7 указывает, что байт ModR / M инструкции использует только r / m (регистр)или память) операнд. Поле reg содержит цифру, которая обеспечивает расширение кода операции инструкции.
Единственное, что вам не хватает, это то, что call dword ptr [fp]
- это текст, сгенерированный дизассемблером. Он никогда не был собран, и как будет собран, зависит от того, как определено fp
. Дизассемблер знает из отладочной информации, что компилятор сгенерировал, где локальная переменная fp
живет в стеке, и знает, что [ebp - 8]
может использоваться для доступа к ней. Он отображал fp
вместо [ebp - 8]
, потому что первое было бы более значимым в большинстве случаев. Вы сможете увидеть это позже, сняв флажок «Показать имена символов».
Обратите внимание, что строка call std::operator<<std:char_traits<char> >
не может быть собрана независимо от того, как определены std
, operator
и т. Д., И т. Д. показывает, что разборка, на которую вы смотрите, на самом деле не предназначена для сборки. Это часто имеет место с дизассемблерами. Вывод должен быть информативным, лучшей альтернативой, чем просмотр последовательности шестнадцатеричных байтов. Это не должен быть обратимый процесс.