Как реализован оператор «>» (для 32-битных целых)? - PullRequest
3 голосов
/ 23 декабря 2010

Допустим, что среда x86.
Как компиляторы компилируют оператор ">" для 32-битных целых чисел.
Логично, я имею в виду. Без каких-либо знаний о сборке.

Допустим, код языка высокого уровня:

int32 x, y;
x = 123;
y = 456;
bool z;
z = x > y;

Что делает компилятор для вычисления выражения x > y?

Выполняет ли он что-то вроде (при условии, что x и y являются положительными целыми числами):

w = sign_of(x - y);
if (w == 0)
   // expression is 'false'
else if (w == 1)
   // expression is 'true'
else
   // expression is 'false'

Есть ли ссылки на такую ​​информацию?

Ответы [ 5 ]

4 голосов
/ 23 декабря 2010

Ну, по логике это что-то , как это.Дело в том, что «сравнить два целых числа» - это вообще примитивная операция практически на любой машине, поэтому с точки зрения машины, если просто выполнить сравнение.Точные детали отличаются от архитектуры к архитектуре, но в целом у вас будет что-то вроде инструкции CMP, которая оставляет код условия или другой такой сигнал управления для «меньше», «равно» и «больше, чем».Таким образом, сгенерированный код будет выглядеть примерно так:

         LD A, X    ; value of x into register A
         LD B, y    ;
         CMP        ; compare reg A with reg B

. В этот момент код результата имеет ответ.Если вы хотите сохранить результат, то вы используете условный вид, который у вас есть -

         JMPGE @FALSE ; goto label FALSE if >=
         STO   Z, 0x1 ; put a hex 1 into location Z
         JMP   @END   ; jump to the end
FALSE:   STO   Z, 0x0
END:
1 голос
/ 23 декабря 2010

Я уверен, что целочисленные сравнения реализованы на уровне процессора.На этом уровне вы обычно смотрите на что-то вроде следующей логики:

x > y if y - x < 0

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

Чтобы немного расширить это, из описания инструкции CMP в x86 , к которой компилятор должен скомпилировать оператор >, но отображает более непосредственнок оператору <=>, доступному на некоторых языках.

Сравнивает первый операнд источника со вторым операндом источника и устанавливает флаги состояния в регистре EFLAGS в соответствии с результатами.Сравнение выполняется путем вычитания второго операнда из первого операнда, а затем установки флагов состояния таким же образом, как инструкция SUB.

Ссылка на SUB.

После инструкции CMP компилятору необходимо выполнить одну или несколько условных инструкций, но именно так работает фактическое сравнение.

0 голосов
/ 03 августа 2013

Все сравнения в x86 (и любые архитектуры, которые используют флаги) реализуются путем вычитания, а затем устанавливаются некоторые флаги в зависимости от результата. Затем процессор может использовать эти флаги для определения любых операторов сравнения, таких как>,> =, =, <=, <</p>

x86 flags register

Например, чтобы проверить, равны ли два значения, он проверит, равен ли результат нулю (ZF = 1). Чтобы проверить Ниже приведены некоторые условия сравнения на x86. Вы можете увидеть их здесь

JE      Jump if equal                           ZF = 1  74  0F 84
JZ      Jump if zero

JNE     Jump if not equal                       ZF = 0  75  0F 85
JNZ     Jump if not zero

JB      Jump if below               unsigned    CF = 1  72  0F 82
JNAE    Jump if not above or equal
JC      Jump if carry

JNB     Jump if not below           unsigned    CF = 0  73  0F 83
JAE     Jump if above or equal
JNC     Jump if not carry

JBE     Jump if below or equal      unsigned    CF = 1 or ZF = 1 76 0F 86
JNA     Jump if not above

JA      Jump if above               unsigned    CF = 0 and ZF = 0 77 0F 87
JNBE    Jump if not below or equal

Некоторые архитектуры (например, MIPS) не используют флаги, а используют аппаратный компаратор, а затем устанавливают регистр в какое-то конкретное значение

0 голосов
/ 23 декабря 2010

Мне кажется, я нашел хорошую ссылку:

http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-2.html#HEADING2-244

0 голосов
/ 23 декабря 2010

Обычно (y - x) & INT32_SIGN_BIT для микрокода.

64-разрядные сравнения на 32-разрядных архитектурах имеют тенденцию быть более интересными, поскольку 64-разрядный знаковый бит может не распознаваться как истинное значение, и вам необходимо принудительно выполнитьчек, т.е. ((y - x) & INT64_SIGN_BIT) != 0.

...