Правильный способ вычитания двух 64-битных чисел в сборке x86

Я использую 32-битную систему и имею 64-битное число, сохраненное в EDX:EAX. Я пытаюсь вычесть число, сохраненное в ESI:EDI, правильно ли это? Я почти уверен, что это не потому, что после 3 итераций результаты неверны.

sub %esi, %edx          #Subtract two 64 bit numbers
sub %edi, %eax

person user2499298    schedule 24.03.2014    source источник
comment
Найдите sbb. Сначала вычтите младшее двойное слово, затем вычтите старшее двойное слово с заимствованием (так же, как перенос).   -  person Frank Kotler    schedule 24.03.2014
comment
Если у вас есть SSE2 (или даже просто MMX), может быть эффективнее использовать psubq xmm0, xmm1. Но, вероятно, только в том случае, если у вас есть несколько 64-битных операций или входы и выходы уже находятся в памяти. (Переход между xmm и целочисленными регистрами стоит больше, чем sub/sbb, но осторожное использование xmm-регуляторов может снизить нагрузку на целочисленные регистры.)   -  person Peter Cordes    schedule 08.11.2017


Ответы (1)


Вам нужно внести два изменения:

  1. Сначала вычтите младшие 32 бита, а не старшие.
  2. Если вычитание младших 32-битных разрядов сгенерировало borrow, вам нужно вычесть еще один из старших разрядов. К счастью, ЦП запоминает, если был заимствование (в carry flag CF), и есть инструкция вычитания с заимствованием, SBB

Вот окончательный код

sub %edi, %eax          # Subtract low order 32-bits, borrow reflected in CF
sbb %esi, %edx          # Subtract high order 32-bits, and the borrow if there was one
person amdn    schedule 24.03.2014
comment
Большое спасибо за ответы на многие мои вопросы, amdn. Мои коллеги и я как бы попали в тупик из-за проблемы, которую представляет эта часть кода. При этом я использую 32-разрядную систему Ubuntu Linux, и поправьте меня, если я ошибаюсь, но нет доступа к sbb на 32-разрядной версии? Я просматривал некоторую документацию, и в ней говорилось, что она доступна только для X=arch 64. Может ли это быть связано с тем, что я использую синтаксис AT&T с ассемблером GNU AS? - person user2499298; 24.03.2014
comment
SBB доступен всем с 8086 года. Может быть, ассемблер как-то кривоват, но я никак не могу понять, почему. - person Seva Alekseyev; 24.03.2014
comment
Я думаю, что нашел ссылку, в которой говорится, что sbbq (q = четверное слово или 64-битное) доступно только в 64-битном режиме. Вам следует использовать sbbl, вот эта ссылка docs.oracle. com/cd/E19253-01/817-5477/eoizh/index.html - person amdn; 24.03.2014