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

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

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

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

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


person b0kiii    schedule 07.10.2019    source источник
comment
Существуют библиотеки для произвольной математики ширины / точности.   -  person Yunnosch    schedule 07.10.2019
comment
ссылка на эту аналогичную 32-битную os calc 64bit long long int   -  person clucle    schedule 07.10.2019
comment
Это зависит от вашей платформы и набора инструментов, который вы не указали.   -  person Jabberwocky    schedule 07.10.2019
comment
Проверьте nand2tetris.org - это хорошо для создания такого фундаментального понимания   -  person gstukelj    schedule 07.10.2019


Ответы (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 последовательных цикла доступа.

person the busybee    schedule 07.10.2019
comment
Спасибо, но я не совсем понял, почему первое добавление сделано без переноски. Могли бы вы объяснить? - person b0kiii; 07.10.2019
comment
Спасибо тебе! Отличное объяснение! - person b0kiii; 07.10.2019

Многие (все, что я знаю ...) процессоры имеют так называемый «флаг переноса» (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 и сначала требовать сброса флага переноса.

person hyde    schedule 07.10.2019

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

person Erlkoenig    schedule 07.10.2019

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

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

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

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

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

person Steve Summit    schedule 07.10.2019