В чем разница между вычитанием `x` и добавлением` -x` на машину x86?

Есть ли различия в семантике? Возможно ли, что кто-то из них будет быстрее при определенных обстоятельствах?

3 ответа

Если у вас есть -x precomputed, то sub smth, x и add smth, -x будут выполняться одинаково быстро.

Семантически, будет разница в терминах состояния флагов.

Рассмотрим выполнение 8-битного сложения и вычитания:

0x01 - 0x01 = 0x00, CF = 0
0x01 + 0xFF = 0x00, CF = 1


В дополнение к разным флагам, если x является константой, выбор одного или другого может привести к более короткому кодированию (редко).

Добавить и вычесть, оба имеют форму op r/m32, imm8, где непосредственный операнд является байтом, но этот байт расширен. Таким образом, add edx, 128 нужно будет закодировать с помощью dword немедленного действия, но sub edx, -128 может быть закодирован с расширением знака (сохранение 3 байта).


Как отметил Алексей Фрунзе, в состоянии флага есть разница. Кроме того, существует разница в количестве возможных отображаемых значений. В двухкомпонентной системе номеров есть еще одно отрицательное значение, чем положительные. Добавление отрицательного числа позволит вам воспользоваться этим, вычитая положительное число, не будет.

EDIT:

Основная проблема заключается в том, что то, что мы обычно считаем "целыми", на самом деле не целыми. В математических терминах они являются членами кольцом факторов, понятием из абстрактной алгебры. Это означает, что для каждого 32-битного "целого" a существует еще 32-битное "целое число" b, такое что a + b = 0. Являются ли эти цифры "позитивными" или "негативными", являются просто интерпретацией. Это означает, что моя точка верна и неверна. В терминах факторного кольца это неверно, но с точки зрения нашей обычной интерпретации это правильно. Должно быть некоторое число, которое мы можем вычесть и получить тот же результат, как если бы мы добавили -2147483248. Это число не 2147483248, однако, что кажется противоречащим интуиции.

licensed under cc by-sa 3.0 with attribution.