брюшной пресс блока x86 () реализация?

Я должен получить различие 2 целых чисел со знаком. Есть ли ABS () функция в x86 ассемблере, таким образом, я могу сделать это. Любая справка значительно ценилась бы.

20
задан Paul R 14 April 2010 в 17:21
поделиться

5 ответов

Есть инструкция SUB, если вы хотите выполнить AB. HTH

{{1} }
0
ответ дан 29 November 2019 в 22:38
поделиться

Если это сборка x86, следующая согласно постоянно полезной википедии должна работать. Вычтите одно значение из другого, а затем используйте эти инструкции для получения результата:

cdq
xor eax, edx
sub eax, edx
17
ответ дан 29 November 2019 в 22:38
поделиться

Если вы хотите правильно обрабатывать все случаи , вы не можете просто вычесть, а затем взять абсолютное значение. У вас возникнут проблемы, потому что разница двух целых чисел со знаком не обязательно может быть представлена ​​как целое число со знаком. Например, предположим, что вы используете 32-битные целые числа с дополнением до 2 и хотите найти разницу между INT_MAX ( 0x7fffffff ) и INT_MIN ( 0x80000000 ). Вычитание дает:

0x7fffffff - 0x80000000 = 0xffffffff

, что равно -1 ; когда вы берете абсолютное значение, вы получаете результат 1 , тогда как фактическая разница между двумя числами составляет 0xffffffff , интерпретируемая как целое число без знака ( UINT_MAX ) .

Разница между двумя целыми числами со знаком всегда может быть представлена ​​как целое число без знака. Чтобы получить это значение (с аппаратным дополнением 2s), вы просто вычитаете меньший ввод из большего и интерпретируете результат как целое число без знака; нет необходимости в абсолютном значении.

Вот один (из многих, и не обязательно лучший) способ сделать это на x86, предполагая, что два целых числа находятся в eax и edx :

    cmp   eax,  edx  // compare the two numbers
    jge   1f
    xchg  eax,  edx  // if eax < edx, swap them so the bigger number is in eax
1:  sub   eax,  edx  // subtract to get the difference
14
ответ дан 29 November 2019 в 22:38
поделиться

Предполагая, что ваши целые числа находятся в регистрах MMX или XMM, используйте psubd для вычисления разницы, затем pabsd , чтобы получить абсолютное значение разницы.

Если ваши целые числа находятся в простых, «обычных» регистрах, выполните вычитание, а затем трюк cdq , чтобы получить абсолютное значение. Это требует использования некоторых специальных регистров ( cdq sign-extends eax в edx , без использования других регистров), так что вы можете делать что-то с другими кодами операций. Например:

mov  r2, r1
sar  r2, 31

вычисляет в регистре r2 знаковое расширение r1 (0, если r1 положительное значение или ноль, 0xFFFFFFFF, если r1 ] отрицательно). Это работает для всех 32-битных регистров r1 и r2 и заменяет инструкцию cdq .

4
ответ дан 29 November 2019 в 22:38
поделиться

Короткий, но простой способ с использованием инструкции условного перемещения (я думаю, доступна Pentium и выше):

; compute ABS(r1-r2) in eax, overwrites r2
mov eax, r1
sub eax, r2
sub r2, r1
cmovg eax, r2

Подкоманда устанавливает флаги так же, как инструкция cmp.

4
ответ дан 29 November 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: