Запись двоичных данных на с ++ - PullRequest
2 голосов
/ 17 октября 2011

Я нахожусь в процессе сборки ассемблера для довольно необычной машины, которую я и несколько других людей собираем. Эта машина требует 18 битных инструкций, и я пишу на ассемблере на C ++.

Я собрал все инструкции в вектор из 32-разрядных целых чисел без знака, ни одна из которых не больше, чем та, которую можно представить с помощью 18-разрядного числа без знака.

Однако, по-моему, нет никакого способа (насколько я могу судить) вывести такое необычное количество битов в двоичный файл на C ++, кто-нибудь может мне помочь с этим.

(Я также хотел бы использовать структуры stdio и File в C. Однако, по-видимому, пока нет никакого способа вывести такое произвольное количество битов).

Спасибо за вашу помощь.

Редактировать: Похоже, я не указал, как инструкции будут храниться в памяти достаточно хорошо.

Инструкции непрерывны в памяти. Скажите, что инструкции начинаются с места 0 в памяти:

Первая инструкция будет в 0. Вторая инструкция будет в 18, третья инструкция будет в 36 и т. Д.

В инструкциях нет пробелов или отступов. При необходимости может быть несколько лишних нулей в конце программы.

Машина использует инструкции с прямым порядком байтов. Таким образом, инструкция, хранящаяся как 3, должна соответствовать: 000000000000000011

Ответы [ 5 ]

3 голосов
/ 17 октября 2011
  • Держите восьмибитный аккумулятор.
  • Сдвигать биты из текущей инструкции в аккумулятор до тех пор, пока:
    • аккумулятор заполнен; или
    • В текущей инструкции не осталось битов.
  • Всякий раз, когда аккумулятор полон:
    • Запишите его содержимое в файл и очистите его.
  • Всякий раз, когда от текущей инструкции не осталось битов:
    • Перейти к следующей инструкции.
  • Когда не осталось никаких инструкций:
    • Сдвигайте нули в аккумулятор, пока он не заполнится.
    • Напишите его содержание.
    • Конец.

Для n инструкций, это оставит (8 - 18 n mod 8) нулевые биты после последней инструкции.

2 голосов
/ 17 октября 2011

Существует множество способов достижения одного и того же конечного результата (я полагаю, что конечный результат представляет собой плотную упаковку этих 18 битов).

Простой способ - создать упаковщик битовКласс, который принимает 32-битные слова и генерирует буфер, который упаковывает 18-битные слова из каждой записи.Класс должен будет немного сдвинуться, но я не ожидаю, что это будет особенно сложно.Последний байт может иметь несколько нулевых битов в конце, если исходная длина вектора не кратна 4. Как только вы передадите все свои слова этому классу, вы можете получить буфер упакованных данных и записать его в файл.

2 голосов
/ 17 октября 2011

Вы можете представить свои данные в bitset , а затем записать набор битов в файл. Не будет работать с функцией записи fstreams, но есть способ , который описан здесь ...

0 голосов
/ 17 октября 2011

Просто выведите их в файл как 32-разрядные целые числа без знака, как у вас в памяти, с порядком байтов, который вы предпочитаете.

А затем, когда загрузчик / eeprom Writer / JTAG или любой другой метод, который вы используетеиспользуйте для отправки кода на компьютер для каждого прочитанного 32-битного слова, просто пропустите 14 более значимых битов и отправьте целые 18 битов цели.

Если, конечно, вы не написалиFAT драйвер для вашей машины ...

0 голосов
/ 17 октября 2011

Краткий ответ: ваша программа на C ++ должна выводить 18-битные значения в формате, ожидаемом вашей необычной машиной.

Нам нужна дополнительная информация, в частности, тот формат, который ожидает ваша "необычная машина", илиточнее, формат, который должен выводить ваш ассемблер.Как только вы поймете, какой формат выходного файла вы генерируете, ответ должен быть простым.

Один возможный формат - я здесь все продумываю - это то, что мы могли бывозьмите две из ваших 18-битных инструкций:

         instruction 1       instruction 2     ...
       MSB            LSB  MSB            LSB  ...
bits → ABCDEFGHIJKLMNOPQR  abcdefghijklmnopqr  ...

... и запишите их в 8-битный / байтовый файл следующим образом:

KLMNOPQR CDEFGHIJ 000000AB klmnopqr cdefghij 000000ab ...

... это в основном устраиваетзначения в форме "little-endian", с 6 нулевыми битами, дополняющими 18-битные значения до 24 бит.

Но я предполагаю: заполнение, little-endianness, количество бит /байт и т. д. Без дополнительной информации трудно сказать, является ли этот ответ хотя бы отдаленно близким к правильному, или это именно то, что вам нужно.

Другая возможность - это плотная упаковка:

ABCDEFGH IJKLMNOP QRabcdef ghijklmn opqr0000

или

ABCDEFGH IJKLMNOP abcdefQR ghijklmn 0000opqr

... но я сделал предположение о том, куда идут угловые дела.

...