2015-12-21 3 views
2
leal -0x61(%edx), %eax 
cmpl $0x19, %eax 
ja ...     ;jump if edx is not between 0x61-0x7a 

В соответствии с описанием приведенный фрагмент кода проверяет, находится ли edx между 0x61-0x7a. Если нет, прыжок берется. Как я понимаю ja проверяет флаги ZF и CF, anf прыгает, если они равны нулю. Единственное, что, я думаю, я понимаю, это то, что вторая строка, которая вычисляет edx-0x7a. Если edx < 0x7a, CF установлен в 1, и переход не выполняется.Понимание проверки интервалов сборки

  1. Как проверено, что edx больше 0x61? Не переустанавливает ли вторую линию CF все время?

  2. Давайте забудем вторую строчку. Если edx> 0x61 CF равно нулю, то скачок будет выполнен. Это не соответствует описанию.

+3

Это немного трюк. Главное отметить, что вы эффективно нормализуете нижнюю часть проверки конца диапазона до 0x00 путем вычитания 0x61 из _EDX_. Ключевая часть здесь заключается в том, что _JA_ основан на ** неподписанном ** сравнении. Таким образом, вы сравниваете с верхним концом нормализованного диапазона с 0x19. Если сравнение ** unsigned ** (без знака важно) выше 0x19, чем _EDX_ изначально было вне 0x61 до 0x7a. –

+3

Вы можете спросить, что произойдет, если _EDX_ был изначально ниже 0x61. Вычитание сделает их отрицательными, однако сравнение без знака рассматривает их как очень большие целые числа с самым значительным набором бит. например, если в _EDX_ было 0x60. 0x60-0x61 = -1. -1 = 0xFFFFFFFF. Как беззнаковое число, которое обтекает верхний конец целочисленного диапазона. –

ответ

2

ja означает скачок, если выше (без знака), а не больше (подпись). Майкл Петч уже ответил на это в комментариях, но я подойду к нему несколько иначе, если это будет полезно.

В C, это делает

if (((unsigned)edx - 0x61U) > 0x19) 
    goto ...; 

Использование без знака сравнения подписанных значений дает >= 0 бесплатно, потому что отрицательные Подписанные значения становятся большие положительные неподписанные значения, больше, чем наибольшее значение со знаком (INT_MAX), поэтому сравнение будет иметь тот же результат, что и для знакового значения выше вашего порога.

Вычитание 0x61LEA) сдвигает диапазон от 0x61-0x7a к 0-0x19, что позволяет одному беззнаковое сравнить, чтобы проверить обе границы.


2.: Обратите внимание, что комментарий на ja говорит о диапазоне edx, в то время как cmp тестирует eax (после вычитания).