32-битные операции на 8-битной архитектуре

Я просто хочу спросить, можно ли получить 32-битные операции на 8-битной архитектуре, и если да, то как?

Я думал об этом некоторое время, и лучшая идея, которая у меня есть, - это typedef char[N] чтобы получить типы размером от N байтов, а затем реализовать такие функции, как add(char *, char *).

Заранее спасибо!

(Я использую про процессор 6502)

4 ответа

Вы отметили свой вопрос буквой "C", поэтому в данном ответе это учтено.

Большинство известных мне компиляторов C для 8-битных систем имеют longтипы. Вы можете просто использовать их.


Сказав это, как это работает?

Все распространенные 8-битные процессоры имеют специальный 1-битный флаг, который принимает перенос / заимствование из 8-битных операций. И у них есть инструкции сложения и вычитания, которые учитывают этот флаг. Таким образом, 32-битное сложение будет переведено в такую ​​последовательность:

    ; 1st operand in R0 to R3
    ; 2nd operand in R4 to R7
    ; addition works only with A(ccumulator)
    ; result goes into R0 to R3
    MOV     A,R0
    ADD     A,R4
    MOV     R0,A
    MOV     A,R1
    ADDC    A,R5
    MOV     R1,A
    MOV     A,R2
    ADDC    A,R6
    MOV     R2,A
    MOV     A,R3
    ADDC    A,R7
    MOV     R3,A

Подумайте, как вы рассчитываете суммы на бумаге. Нет необходимости добавлять перенос к самой правой цифре, наименее значимой. Поскольку справа нет "ничего", переноса нет. Мы можем интерпретировать каждый 8-битный шаг как однозначную операцию над цифрой системы счисления с основанием 256.

Для битовых операций нет необходимости в переносе или заимствовании.


Другая мысль: что вы называете 8-битной системой? Когда инструкция может обрабатывать 8 бит параллельно или когда ширина шины данных составляет всего 8 бит?

В последнем случае мы можем рассмотреть, например, процессор 68008. Внутри 32-битного процессора его шина данных имеет всего 8 бит. Здесь вы будете использовать 32-битные инструкции. Если процессор считывает или записывает 32-битное значение из / в память, он автоматически генерирует 4 последовательных цикла доступа.

В общем, ответ на вопрос "Могу ли я выполнять M-битную арифметику на процессоре, который имеет только N бит?" это "Конечно да!"

Чтобы понять, почему: еще в школе вы, вероятно, выучили свои таблицы сложения и умножения только для 10+10 и 10×10. Тем не менее, у вас нет проблем с сложением, вычитанием или умножением чисел, состоящих из любого количества цифр.

И, проще говоря, именно так компьютер может работать с числами, превышающими его разрядность. Если у вас есть два 32-битных числа, и вы можете складывать их только по 8 бит за раз, ситуация почти такая же, как при наличии двух 4-значных чисел, которые вы можете добавлять только по одной цифре за раз. В школе вы научились складывать отдельные пары цифр и обрабатывать перенос. Точно так же компьютер просто складывает пары 8-битных чисел и обрабатывает перенос. Вычитание и умножение подчиняются тем же правилам, которым вы учились в школе. (Деление, как всегда, может быть сложнее, хотя алгоритм длинного деления, который вы выучили в школе, часто также является хорошим началом для длинного компьютерного деления.)

Это помогает иметь очень четкое представление о системах счисления с основанием, отличным от 10. Я сказал: "Если у вас есть два 32-битных числа и вы можете складывать их только по 8 бит за раз, ситуация почти такая же, как если бы у вас было два 4-значные числа, которые можно добавлять только по одной цифре за раз ". Теперь, когда вы берете два 32-битных числа и складываете их по 8 бит за раз, оказывается, что вы выполняете арифметические операции с базой 256. Поначалу это звучит безумно: большинство людей никогда не слышали о базе 256, и это похоже, что работать на такой большой базе было бы невероятно сложно. Но на самом деле это совершенно просто, если подумать.

(Ради удовольствия, я однажды написал код для арифметических вычислений с произвольно большими числами, и он работает с базой 2147483648. Поначалу это звучит действительно безумно, но это так же разумно, и на самом деле так работают большинство библиотек произвольной точности Хотя на самом деле "настоящие" библиотеки, вероятно, используют базу 4294967296, потому что они умнее меня в обработке переносов, и они не хотят тратить впустую ни единого бита.)

Если вы используете стандартный int / long типов, компилятор автоматически поступит правильно. longимеет (как минимум) 32 бита, поэтому нет необходимости работать с битами переноса вручную; компилятор уже на это способен. По возможности используйте стандартныйuint32_t/int32_tтипы для удобочитаемости и переносимости. Изучите дизассемблированный код, чтобы увидеть, как компилятор работает с 32-битной арифметикой.

Многие (все, что я знаю...) процессоры имеют так называемый "флаг переноса" (1 бит), который устанавливается, когда сложение или вычитание вызывает циклический переход. По сути, это дополнительный бит для вычислений. Затем у них есть варианты сложения и вычитания, которые включают этот флаг переноса. Таким образом, вы можете выполнить (например) 32-битное сложение, выполнив 4 8-битных сложения с переносом.

Пример псевдокода, машина с прямым порядком байтов (таким образом, байт 0 из 4-х байтовых результатов является наименее значимым байтом):

carry,result[0] = opA[0] + opB[0]
carry,result[1] = opA[1] + opB[1] + carry
carry,result[2] = opA[2] + opB[2] + carry
carry,result[3] = opA[3] + opB[3] + carry
if carry == 1, overflow the 32 bit result

Первая инструкция сложения может называться ADD (не включает перенос, просто устанавливает его), а следующие добавления могут называться ADC (включает перенос и устанавливает его). Некоторые процессоры могут иметь только инструкцию ADC и сначала требовать сброса флага переноса.

Другие вопросы по тегам