Переносимость кода C для различных схем адресации памяти

Если я правильно понимаю, спецификация DCPU-16 для 0x10c описывает 16-битное адресное пространство, где каждое смещение обращается к 16-битному слову, а не к байту, как в большинстве других архитектур памяти. Это имеет некоторые любопытные последствия, например, я полагаю, что sizeof(char) а также sizeof(short) оба вернутся 1,

Возможно ли сохранить код на C переносимым между такими разными схемами адресации памяти? О чем следует помнить?

редактировать: возможно, я должен был привести более конкретный пример. Допустим, у вас есть некоторый сетевой код, который работает с потоками байтов. Вы отбрасываете половину своей памяти, помещая только один байт на каждый адрес, чтобы код мог остаться прежним, или вы обобщаете все с помощью битовых сдвигов, чтобы иметь дело с N байтами на смещение?

edit2: ответы, кажется, сосредоточены на вопросе размеров типов данных, что не было смысла - я даже не должен был упомянуть это. Вопрос в том, как справиться с потерей способности обращаться к любому байту в памяти с указателем. Разумно ли ожидать, что код будет агностиком по этому поводу?

4 ответа

Это вполне возможно. Грубо говоря, базовые целочисленные типы данных C имеют размеры, которые поддерживают:

sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)

Выше не совсем то, что говорит спецификация, но это близко.

Как указывает awoodland в комментарии, вы также ожидаете, что компилятор C для DCPU-16 будет иметь CHAR_BIT == 16,

Бонус за то, что не предполагал, что DCPU-16 будет иметь sizeof (char) == 2Это распространенная ошибка.

Когда вы говорите "потеря способности обращаться к байту", я предполагаю, что вы имеете в виду "бит-октет", а не "символ". Переносимый код должен только предполагать CHAR_BIT >= 8, На практике архитектуры, не имеющие байтовой адресации, часто определяют CHAR_BIT == 8и позволить компилятору генерировать инструкции для доступа к байту.

Я на самом деле не согласен с ответами, предлагающими: CHAR_BIT == 16 как хороший выбор. Я бы предпочел: CHAR_BIT == 8, с sizeof(short) == 2, Компилятор может обрабатывать сдвиг / маскирование, как это происходит для многих архитектур RISC, для байтового доступа в этом случае.

Я предполагаю, что Нотч пересмотрит и уточнит спецификацию DCPU-16; уже есть запросы на механизм прерывания и дальнейшие инструкции. Это эстетический фон для игры, поэтому я сомневаюсь, что в ближайшее время будут официальные спецификации ABI. Тем не менее, кто-то будет работать над этим!

Редактировать:

Рассмотрим массив char в C. Компилятор упаковывает 2 байта в каждый собственный 16-битный word памяти DCPU. Так что, если мы получим, скажем, 10-й элемент (индекс 9), извлеките слово # [9 / 2] = 4 и извлеките байт # [9 % 2] = 1.

Пусть 'X' будет начальным адресом массива, а 'I' будет индексом:

SET J, I
SHR J, 1    ; J = I / 2
ADD J, X    ; J holds word address
SET A, [J]  ; A holds word
AND I, 0x1  ; I = I % 2 {0 or 1}
MUL I, 8    ; I = {0 or 8} ; could use: SHL I, 3
SHR A, I    ; right shift by I bits for hi or lo byte.

Регистр A содержит "байт" - это 16-битный регистр, поэтому верхнюю половину можно игнорировать. В качестве альтернативы, верхняя половина может быть обнулена:

AND A, 0xff ; mask lo byte.

Это не оптимизировано, но оно передает идею.

Равенство выглядит примерно так:

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

short тип может быть 1и на самом деле, может быть, вы даже хотите int типа быть 1 слишком на самом деле (я не читал спецификации, но я предполагаю, что нормальный тип данных - 16 бит). Этот материал определяется компилятором.

Для практичности, компилятор может захотеть установить long к чему-то большему, чем int даже если это требует от компилятора дополнительной работы (например, реализации сложения / умножения и т. д. в программном обеспечении).

Это не проблема адресации памяти, а скорее вопрос гранулярности.

Да, вполне возможно портировать код C

с точки зрения передачи данных было бы целесообразно либо упаковать биты (или использовать сжатие), либо отправить в 16-битных байтах

поскольку процессор почти полностью взаимодействует только с (игровыми) внутренними устройствами, которые, вероятно, также будут все 16-битными, это не должно быть реальной проблемой

Кстати, я согласен, что CHAR_BIT должно быть 16, так как (IIRC) каждый символ должен быть адресуемым, поэтому CHAR_BIT ==8 потребуется sizeof(char*) ==2 что сделает все остальное слишком сложным

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