Сравнение 128-битных целых чисел без знака в сборке x86-32 - PullRequest
1 голос
/ 11 июля 2019

Я пытаюсь провести сравнение между 2 128-битными целыми числами, и я просто не могу понять это!

В частности, у меня есть целая куча IP-адресов IPv6 (начальный и конечный адресавыделение блоков), и я пытаюсь установить, находится ли определенный IP-адрес между этими блоками, так что это не прямое сравнение, больше похоже на попытку проверить, больше ли начальный адрес и меньше ли конечный адрес.

IЯ использую WinAsm Studio с MASM32, если это что-то меняет.

Выполнить это с адресами IPv4 просто, однако я понятия не имею, как это сделать с целыми 128-битными без знака (4 x DWORD).

Заранее спасибо.

1 Ответ

3 голосов
/ 11 июля 2019

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

На процессоре, который использует cmp и регистр флагов, это делается следующим образом:

  • Сравните старшие части (например, старшие 32 бита) чисел (cmp инструкция)
  • Если не равно «Равно», перейдите к «EndOfCompare» (x86: jne инструкция)
  • Сравните следующие части (например, 32 бита) чисел
  • Если не равно «Равно», перейдите к «EndOfCompare»
  • ...
  • Сравните следующие части (например, 32 бита) чисел
  • Если не равно «Равно», перейдите к «EndOfCompare»
  • Сравните младшие части (например, младшие 32 бита) чисел
  • "EndOfCompare":
    В этот момент регистр флагов содержит информацию о порядке (a<b, a=b или a>b) двух больших чисел, точно так же, как вы делали простую инструкцию cmp, сравнивающую два маленьких числа.

К сожалению, этот простой вариант будет работать только с числами без знака.

Кстати, обычно блок "выровнен" в пространстве IP-адресов, поэтому вам нужно только проверить маску младших битов и сравнить старшие биты на равенство.

Проверка для (A AND MASK) = (B AND MASK) может выполняться следующим образом на 32-разрядном процессоре:

mov ecx, part 1 of A
xor ecx, part 1 of B
and ecx, part 1 of MASK

mov eax, part 2 of A
xor eax, part 2 of B
and eax, part 2 of MASK
or  ecx, eax

mov eax, part 3 of A
xor eax, part 3 of B
and eax, part 3 of MASK
or  ecx, eax
...

В случае 128-битного числа вам нужно 4 "части".

Не имеет значения, является ли "часть 1" старшим или младшим битом чисел.

Если (A AND MASK) = (B AND MASK) имеет значение true, ecx будет иметь значение 0 (и флаг нуля будет установлен из-за инструкции or).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...