Понимание cmp в сборке - PullRequest
0 голосов
/ 08 июня 2019

Я смотрю код сборки, который выглядит следующим образом:

cmp dword [rbp-0x4 {var_c}], 0x0
jne 0x12c0

Для меня это звучит так:

Сравните значение чего-либо с нулем, и если нет ошибки (то есть они совпадают), перейдите к 0x12c0.

Это правильно? Я не понимаю, что такое [rbp-0x4 {var_c}] или почему мы сравниваем это с нулем.

Я попытался проследить график, чтобы узнать, что это за переменные, и получил следующее:

  • 0x4 = uint8_t file_class = 0x2
  • var_c = In Set of Values {0, 1}
  • rbp похоже на то, что выталкивается из основного

Буду признателен за любую помощь в понимании этого. Я ищу разъяснения относительно того, что сравнивается в выражении cmp.

Ответы [ 2 ]

2 голосов
/ 08 июня 2019

rbp похоже на то, что выдвигается из основного

rbp - это один регистр ЦП, который (как и все регистры ЦП) хранит значение.

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

Адрес (место в памяти RAM), где хранится определенная локальная переменная, обычно рассчитывается путем вычитания некоторого постоянного значения из значения, хранящегося в регистре rbp.

Я непонять, что такое [rbp-0x4 {var_c}] ...

dword [rbp-0x4] означает: 32-разрядное значение, сохраненное по адресу rbp-4: адрес, который вычисляется путем вычитания значения 4 из значения, сохраненногов реестре rbp.

Компилятор поместил дополнительную информацию для отладчика в двоичный файл.Эта информация говорит о том, что адрес локальной переменной var_c рассчитывается по rbp-4, а адрес локальной переменной some_other_variable вычисляется по rbp-10 и т. Д. *

дизассемблер имеетпрочитайте эту информацию и напечатайте {var_c} после rbp-0x4, чтобы показать, что переменная var_c расположена по адресу rbp-0x4.Таким образом, 32-битное значение "dword [rbp-0x4]", вероятно, является переменной "var_c".

0x4 = uint8_t file_class = 0x2

Я не знаюкакая информация это.Но значение 0x4 здесь не имеет ничего общего со значением 0x4 в строке разборки (rbp-0x4).

... и если нет ошибок (т.е. они совпадают), переход к 0x12c0.

jne означает: " J ump, если n ot e qual".

Это означает, что ЦП будет прыгать, если переменная var_c была , а не равна 0.

Обратите внимание, что в скомпилированном коде, представляющем ветвь if(), инструкция перехода будетобычно переходит, если условие было false :

Если условие false , процессор переходит к части else или к первой инструкции после if() часть.Если условие true , ЦП не прыгает, а выполняет первую инструкцию части if(), которая следует инструкции jne (или аналогичной).

Поскольку ваш пример переходит, если var_c равно не ноль, вероятно, что исходный код был чем-то вроде if(var_c == 0).

2 голосов
/ 08 июня 2019

Не совсем, это больше:

Сравните значение чего-либо с нулем и, если они не равны, прыгните.

Язык ассемблера не имеет понятия"null" и cmp обычно такие же, как sub (вычитание), но без фактического изменения значения.По сути, это:

Установите флаги , как если бы Я вычел ноль из чего-либо.сумма:

if var_c <> 0 then goto label_12c0
...