Маху дал или как можно сравнивать целые числа на БЭСМ-6
В построении интерпретатора-компилятора я продвинулся до момента когда необходимо преобразовать код виртуальной машины в код еще более близкий к железу, т.е. к МЭСМ-6.
Процессор БЭСМ-6, в отличии от современных собратьев, имеет интересную особенность: отсутствие привычных команд ветвления анализирующих условия (флажки) по равенству/неравенству, больше или равно, меньше. Вместо этого каждая команда, которая затрагивает аккумулятор устанавливает режим “омега”, но основе которого формируется признак “омега” на основе значения которого выполняются команды условного перехода UZA и U1A (переход по нулю и 1-це значения “омега”).
Признак “омега” формируется следующим образом:
Соответственно, чтобы запрограммировать:
Необходимо, закодировать a < b так:
Для a == b:
Что как раз очевидно следовало из первого и третьего case.
Но что делать с a <= b ?
Первое что пришло в голову так это выполнить две проверки, сначала на равенство a == b, а потом a < b ведь для этого у нас есть готовые признаки “омега” …
А нужно то было всего лишь применить школьную программу и переставить местами a и b. Маху дал :)
Таким образом:
Для b < a так:
Но, как заметил Леонид, для удобства в БЭСМ-6 есть команда x-a (обратное вычитание), получим:
Для a > b:
Слишком уж наше поколение стало избалованное процессорами с большим количеством инструкций, когда стоит только подумать, а уже есть какая-нибудь VFMADDSUB213PS, с умными компиляторами к ним.
Процессор БЭСМ-6, в отличии от современных собратьев, имеет интересную особенность: отсутствие привычных команд ветвления анализирующих условия (флажки) по равенству/неравенству, больше или равно, меньше. Вместо этого каждая команда, которая затрагивает аккумулятор устанавливает режим “омега”, но основе которого формируется признак “омега” на основе значения которого выполняются команды условного перехода UZA и U1A (переход по нулю и 1-це значения “омега”).
Признак “омега” формируется следующим образом:
switch (ω mode) { case additive: ω = (A[41] != 0); /* A < 0 */ break; case multiplicative: ω = (A[48] != 1); /* abs(A) < 0.5 */ break; case logical: ω = (A[48:1] != 0); /* A != 0 */ break; case 0: ω = 1; }
Соответственно, чтобы запрограммировать:
if (a < b) { … } else { else_block }
Необходимо, закодировать a < b так:
xta a,M1 a-x b,M1 uza else_block ; u1a для a >= b ...
Для a == b:
xta a, M1 aex b, M2 u1a else_block ; uza для a != b
Что как раз очевидно следовало из первого и третьего case.
Но что делать с a <= b ?
Первое что пришло в голову так это выполнить две проверки, сначала на равенство a == b, а потом a < b ведь для этого у нас есть готовые признаки “омега” …
А нужно то было всего лишь применить школьную программу и переставить местами a и b. Маху дал :)
Таким образом:
Для b < a так:
xta b,M1 a-x a,M1 uza else_block ; u1a для b >= a, что эквивалентно a <= b
Но, как заметил Леонид, для удобства в БЭСМ-6 есть команда x-a (обратное вычитание), получим:
Для a > b:
xta a,M1 x-a b,M1 uza else_block ; u1a для a <= b
Слишком уж наше поколение стало избалованное процессорами с большим количеством инструкций, когда стоит только подумать, а уже есть какая-нибудь VFMADDSUB213PS, с умными компиляторами к ним.