Реализуйте битовые операции только с помощью команд ADD, SUB, MUL и DIV - PullRequest
3 голосов
/ 08 августа 2011

Я пишу компилятор - просто для удовольствия и для улучшения моих навыков. Я хотел бы реализовать подмножество языка Си. Проблема в том, что я компилирую на ассемблере теоретический 16-битный RISC-процессор под названием Sextium II (мы использовали его для обучения ассемблеру в нашем университете).

Процессор использует только 16 команд, и ни одна из них не является битовой операцией. Я хотел бы реализовать C-битные операторы - а затем и с плавающей половиной точности - но я не знаю, как реализовать битовые операции, используя только инструкции ADD, SUB, MUL и DIV. Сдвиг битов довольно прост, это просто умножение или деление на 2^n, где n - длина сдвига. Но как насчет AND, OR, NOT или XOR?

EDIT Для ясности: процессор вычисляет только в 16-битной знаковой арифметике U2.

1 Ответ

1 голос
/ 08 августа 2011

Хорошо, если вы посмотрите на таблицу побитовых истин для добавления, например:

a b  c r
0 0  0 0
0 1  0 1
1 0  0 1
1 1  1 0

a и b - входные операнды, r - результат c, - выполнение.

Fromпобитовая перспектива - это XOR.Но чтобы использовать это как общий xor, вам нужно выполнить 16 операций добавления, по одной для каждого бита, плюс всю работу, связанную с маскировкой одного операнда и извлечением результирующего бита.

a b  c r
0 1  0 1
1 1  1 0

Сосредоточение на сложенииснова, но с операндом b, всегда равным единице, вы получаете функцию not.И здесь снова потребуется маскировка и смещение.

Конечно, у вас нет маскировки и сдвига?

Множитель сместится влево, раз 2 - это сдвиг 1, 4, сдвиг 2 и так далее.Точно так же разделение - это сдвиг вправо.Делить на 4 - это сдвиг на 2, делить на 8 - это сдвиг на 3 и так далее.Таким способом можно замаскировать отдельные биты, разделить на 8, чтобы сместить вправо 3, затем умножить на 0x8000, чтобы сместить влево 15, а затем разделить на 0x1000.Будет ли это так же, как и с 0x0008?

Если это сработает, вы можете сказать, умножить на 0x100, затем разделить на 0x100 и получить значение, равное 0xFF00.

это множитель (и деление) со знаком или без знака?или у вас есть оба?

...