Младший байт счетчика команд
Регистры специального назначения
Регистр статуса ( STATUS ) содержит признаки операции (арифметические флаги) АЛУ, состояние контроллера при сбросе и биты выбора страниц для памяти данных.
Регистр статуса доступен для любой команды так же, как любой другой регистр. Однако если регистр STATUS является регистром назначения для команды, влияющей на биты Z, DC или C, то запись в эти три бита запрещается. Кроме того, биты /TO и /PD устанавливаются аппаратно и не могут быть записаны в статус программно. Это следует иметь в виду при выполнении команды с использованием регистра статуса. Например, команда CLRF STATUS обнулит все биты, кроме битов /TOи /PD, а затем установит бит Z=1. После выполнения этой команды регистр статуса может и не иметь нулевого значения (из-за битов /TO и /PD ) STATUS=000uu1uu, где u – неизменяемое состояние. Поэтому рекомендуется для изменения регистрастатуса использовать только команды битовой установки BCF, BSF, MOVWF, которые не изменяют остальные биты статуса. Воздействие всех команд на биты статуса рассматривается в разделе «Описание системы команд».
Регистр конфигурации ( OPTION ) является доступным по чтению и записи регистром, который содержит управляющие биты для конфигурации предварительного делителя (предделителя), внешних прерываний, таймера, а также резисторов «pull-up» на выводах PORTB.
Регистр условий прерывания ( INTCON ) является доступным по чтению и записи регистром, который содержит биты доступа для всех источников прерываний.
Счетчик команд
Счетчик команд PCL и PCLATH имеет разрядность 13 бит. Младший байт счетчика ( PCL ) доступен для чтения и записи и находится в регистре 02h. Старший байт счетчика команд не может быть напрямую записан или считан и берется из регистра PCLATH (PC latch high), адрес которого 0Ah. Содержимое PCLATH передается в старший байт счетчика команд, когда он загружается новым значением.
В зависимости от того, загружается ли в счетчик команд новое значение во время выполнения команд CALL, GOTO, или в младший байт счетчика команд ( PCL ) производится запись, – старшие биты счетчика команд загружаются из PCLATH разными способами, как показано на рисунке 40.4
Команды CALL и GOTO оперируют одиннадцатиразрядным адресным диапазоном, достаточным для смещения в пределах страницы программной памяти объемом 2К слов. Для МК подгруппы PIC16F8X этого хватает. С целью обеспечения возможности расширения памяти команд для будущих моделей МК предусмотрена загрузка двух старших бит счетчика команд из регистра PCLATH .
.
Рисунок 40.4 — Загрузка старших бит счетчика команд
При использовании команд CALL и GOTO пользователь должен убедиться в том, что эти страничные биты запрограммированы для выхода на нужную страницу. При выполнении команды CALL или выполнении прерывания весь тринадцатибитный счетчик команд помещается в стек, поэтому для возвращения из подпрограммы не нужны манипуляции с разрядами PCLATH .
Микроконтроллеры подгруппы PIC16F8X игнорируют значения бит PCLATH , которые используются для обращения к страницам 1, 2 и 3 программной памяти. Однако применять биты PCLATH в качестве ячеек памяти общего назначения не рекомендуется, так как это может повлиять на совместимость с будущими поколениями изделий.
Возможность выполнять арифметические операции непосредственно над счетчиком команд позволяет очень быстро и эффективно осуществлять табличные преобразования в PIC -контроллерах.
Микроконтроллеры подгруппы PIC16F8X имеют восьмиуровневый аппаратный стек шириной 13 бит (рисунок 40.2). Область стека не принадлежит ни к программной области, ни к области данных, а указатель стека пользователю недоступен. Текущее значение счетчика команд посылается в стек, когда выполняется команда CALL или производится обработка прерывания. При выполнении процедуры возврата из подпрограммы (команды RETLW, RETFIE или RETURN) содержимое счетчика команд восстанавливается из стека. Регистр PCLATH при операциях со стеком не изменяется.
Стек работает как циклический буфер. Следовательно, после того как стек был загружен восемь раз, девятая загрузка перепишет значение первой. Десятая загрузка перепишет вторую и т.д. Если стек был выгружен девять раз, счетчик команд становится таким же, как после первой выгрузки.
Признаков положения стека в контроллере не предусмотрено, поэтому пользователь должен самостоятельно следить за уровнем вложения подпрограмм.
Младший байт счетчика команд
Счетчик команд PCL и PCLATH имеет разрядность 13 бит. Младший байт счетчика (PCL) доступен для чтения и записи и находится в регистре 02h. Старший байт счетчика команд не может быть напрямую записан или считан и берется из регистра PCLATH (PC latch high), адрес которого 0Ah. Содержимое PCLATH передается в старший байт счетчика команд, когда он загружается новым значением.
В зависимости от того, загружается ли в счетчик команд новое значение во время выполнения команд CALL, GOTO, или в младший байт счетчика команд (PCL) производится запись, – старшие биты счетчика команд загружаются из PCLATH разными способами, как показано на рис. 5.6.
Рис. 5.6. Загрузка старших бит счетчика команд.
Команды CALL и GOTO оперируют 11-разрядным адресным диапазоном, достаточным для смещения в пределах страницы программной памяти объемом 2К слов. Для МК подгруппы PIC16F8X этого хватает. С целью обеспечения возможности расширения памяти команд для будущих моделей МК предусмотрена загрузка двух старших бит счетчика команд из регистра PCLATH . При использовании команд CALL и GOTO пользователь должен убедиться в том, что эти страничные биты запрограммированы для выхода на нужную страницу. При выполнении команды CALL или выполнении прерывания весь 13-битный счетчик команд помещается в стек, поэтому для возвращения из подпрограммы не нужны манипуляции с разрядами PCLATH .
Микроконтроллеры подгруппы PIC16F8X игнорируют значения бит PCLATH , которые используются для обращения к страницам 1, 2 и 3 программной памяти. Однако применять биты PCLATH в качестве ячеек памяти общего назначения не рекомендуется, так как это может повлиять на совместимость с будущими поколениями изделий.
Возможность выполнять арифметические операции непосредственно над счетчиком команд позволяет очень быстро и эффективно осуществлять табличные преобразования в PIC-контроллерах.
Микроконтроллеры подгруппы PIC16F8X имеют восьмиуровневый аппаратный стек шириной 13 бит (см. рис. 5.4). Область стека не принадлежит ни к программной области, ни к области данных, а указатель стека пользователю недоступен. Текущее значение счетчика команд посылается в стек, когда выполняется команда CALL или производится обработка прерывания. При выполнении процедуры возврата из подпрограммы (команды RETLW, RETFIE или RETURN) содержимое счетчика команд восстанавливается из стека. Регистр PCLATH при операциях со стеком не изменяется.
Стек работает как циклический буфер. Следовательно, после того как стек был загружен 8 раз, девятая загрузка перепишет значение первой. Десятая загрузка перепишет вторую и т.д. Если стек был выгружен 9 раз, счетчик команд становится таким же, как после первой выгрузки.
Признаков положения стека в контроллере не предусмотрено, поэтому пользователь должен самостоятельно следить за уровнем вложения подпрограмм.
5.2.8. Прямая и косвенная адресации
Когда производится прямая 9-битная адресация, младшие 7 бит берутся как прямой адрес из кода операции, а два бита указателя страниц (RP1, RP0) из регистра статуса, как показано на рис. 5.7.
Рис. 5.7. Методы адресации данных.
Признаком косвенной адресации является обращение к регистру INDF. Любая команда, которая использует INDF (адрес 00h) в качестве регистра фактически обращается к указателю, который хранится в FSR (адрес 04h). Чтение косвенным образом самого регистра INDF даст результат 00h. Запись в регистр INDF косвенным образом будет выглядеть как NOP, но биты статуса могут быть изменены. Необходимый 9-битный адрес формируется объединением содержимого 8-битного FSR регистра и бита IRP из регистра статуса (см. рис. 5.7).
Обратите внимание, что некоторые регистры специальных функций располагаются в банке 1. Чтобы адресоваться к ним, нужно дополнительно установить в единицу бит RP0 в регистре статуса.
5.2.9. Порты ввода/вывода
Контроллеры подгруппы PIC16F8X имеют два порта: PORTA (5 бит) и PORTB (8 бит) с побитовой индивидуальной настройкой на ввод или на вывод.
Порт А (PORTA) представляет собой 5-битовый фиксатор, соответствующий выводам контроллера RA . Линия RA4 имеет вход триггера Шмитта и выход с открытым стоком. Все остальные линии порта имеют ТТЛ входные уровни и КМОП выходные буферы. Адрес регистра порта А – 05h.
Каждой линии порта поставлен в соответствие бит направления передачи данных, который хранится в управляющем регистре TRISA, расположенном по адресу 85h. Если бит управляющего TRISA регистра имеет значение 1, то соответствующая линия будет устанавливаться на ввод. Ноль переключает линию на вывод и одновременно выводит на нее содержимое соответствующего регистра-фиксатора порта. При включении питания все линии порта по умолчанию настроены на ввод.
На рис. 5.8 дана схема линий RA порта А.
Рис. 5.8. Схема линий RA порта А. Выводы порта имеют защитные диоды к Vdd и Vss.
Операция чтения порта А считывает состояние выводов порта, в то время как запись в него изменяет состояние триггеров порта. Все операции с портом являются операциями типа «чтение-модификация-запись». Поэтому запись в порт предполагает, что состояние выводов порта вначале считывается, затем модифицируется и записывается в триггер-фиксатор.
Вывод RA4 мультиплексирован с тактовым входом таймера TMR0. Схема линии RA4 порта А приведена на рис. 5.9.
Порт В (PORTB) – это двунаправленный 8-битовый порт, соответствующий выводам RB контроллера и расположенный по адресу 06h. Относящийся к порту В управляющий регистр TRISB расположен на первой странице регистров по адресу 86h. Если бит управляющего TRISB регистра имеет значение 1, то соответствующая линия будет устанавливаться на ввод. Ноль переключает линию на вывод и одновременно выводит на нее содержимое соответствующего регистра защелки. При включении питания все линии порта по умолчанию настроены на ввод.
Рис. 5.9. Схема линии RA4 порта А. Вывод порта имеет защитный диод только к Vss.
У каждой ножки порта В имеется небольшая активная нагрузка (около 100мкА) на линию питания (pull-up). Она автоматически отключается, если эта ножка запрограммирована как вывод. Более того, управляющий бит /RBPU регистра OPTION может отключить (при RBPU=1) все нагрузки. Сброс при включении питания также отключает все нагрузки.
Четыре линии порта В (RB ) могут вызвать прерывание при изменении значения сигнала на любой из них. Если эти линии настроены на ввод, то они опрашиваются и защелкиваются в цикле чтения Q1. Новая величина входного сигнала сравнивается со старой в каждом командном цикле. При несовпадении значения сигнала на ножке и в фиксаторе генерируется высокий уровень. Выходы детекторов «несовпадений» RB4, RB5, RB6, RB7 объединяются по ИЛИ и генерируют прерывание RBIF (запоминаемое в регистре INTCON ). Любая линия, настроенная как вывод, в этом сравнении не участвует. Прерывание может вывести кристалл из режима SLEEP. В подпрограмме обработки прерывания следует сбросить запрос прерывания одним из следующих способов:
- прочитать (или записать в) порт В. Это завершит состояние сравнения;
- обнулить бит RBIF регистра INTCON .
При этом необходимо иметь в виду, что условие «несовпадения» будет продолжать устанавливать признак RBIF. Только чтение порта В может устранить «несовпадение» и позволит обнулить бит RBIF.
Прерывание по несовпадению и программно устанавливаемые внутренние активные нагрузки на этих четырех линиях могут обеспечить простой интерфейс, например, с клавиатурой, с выходом из режима SLEEP по нажатию клавиш.
Схемы линий порта B приведены на рис. 5.10 и 5.11.
Рис. 5.10. Схема линий RB порта B. Выводы порта имеют защитные диоды к Vdd и Vss.
Рис. 5.11. Схема линий RB порта B. Выводы порта имеют защитные диоды к Vdd и Vss.
При организации двунаправленных портов необходимо учитывать особенности организации ввода/вывода данных МК. Любая команда, которая осуществляет запись, выполняет ее внутри как «чтение-модификация-запись». Например, команды BCF и BSF считывают порт целиком, модифицируют один бит и выводят результат обратно. Здесь необходима осторожность. В частности, команда BSF PORTB, 5 (установить в единицу бит 5 порта B) сначала считывает все реальные значения сигналов, присутствующие в данный момент на выводах порта. Затем выполняются действия над битом 5, и новое значение байта целиком записывается в выходные фиксаторы. Если другой бит регистра PORTB используется в качестве двунаправленного ввода/вывода (скажем, бит 0), и в данный момент он определен как входной, то входной сигнал на этом выводе будет считан и записан обратно в выходной триггер-фиксатор этого же вывода, стирая предыдущее состояние. До тех пор, пока эта ножка остается в режиме ввода, никаких проблем не возникает. Однако если позднее линия 0 переключится в режим вывода, ее состояние будет неопределенным.
На ножку, работающую в режиме вывода, не должны нагружаться внешние источники токов («монтажное И», «монтажное ИЛИ»). Большие результирующие токи могут повредить кристалл.
Необходимо выдерживать определенную последовательность обращения к портам ввода/вывода. Запись в порт вывода происходит в конце командного цикла. Но при чтении данные должны быть стабильны в начале командного цикла. Будьте внимательны в операциях чтения, следующих сразу за записью в тот же порт. Здесь надо учитывать инерционность установления напряжения на выводах. Может потребоваться программная задержка, чтобы напряжение на ножке (которое зависит от нагрузки) успело стабилизироваться до начала исполнения следующей команды чтения.
Большая Энциклопедия Нефти и Газа
Дешифратор — адрес — память
Дешифратор адреса памяти декодирует этот адрес. По сигналу Чтение памяти содержимое области памяти 0008 ( число 00) выводится на шину данных. Данные ( число 00) пересылаются в старший байт счетчика команд. [1]
Дешифратор адреса устройства ввода-вывода подобен дешифратору адреса памяти . Поскольку имеются только четыре порта ввода-вывода, достаточно располагать двумя адресными линиями. Дешифратор адреса устройства ввода-вывода декодирует все адреса, посылаемые микропроцессором. Однако порты ввода-вывода откликаются на запрос, посылаемый в форме их адресов, только тогда, когда имеет место совпадение импульсов Чтение ввода-вывода или Запись ввода-вывода с декодированием этих адресов. [2]
Структурная схема типичного ПЗУ представлена на рис. 10.8. Дешифратором адреса памяти является комбинационная схема, которая по требуемому одному из N возможных адресов открывает доступ к соответствующему Af-разрядному слову в матрице памяти M-N. Содержимое этих М разрядов передается затем в выходной буферный распределитель. [4]
Адрес памяти 0001 подается на адресную шину и декодируется дешифратором адреса памяти . [5]
Адрес — двоичное число-появляется на адресной шине микропроцессора и декодируется дешифратором адреса памяти . Если на адресную шину помещен адрес допустимого значения, то схемы управления микропроцессора вырабатывают и посылают по линиям управления импульсные сигналы Чтение памяти или Запись в память. Эти сигналы информируют микропроцессор о необходимости подачи данных на соответствующую шину или получения данных с шины для записи в выбранную область памяти. При записи данных в память предыдущее содержимое соответствующей ее области стирается и заменяется записываемой информацией. Чтение данных из памяти не меняет содержимое области, в которой они находятся. Одни и те же данные можно считывать любое количество раз. Принято говорить, что операция чтения является операцией, не разрушающей информацию. [6]
С каким из перечисленных ниже узлов микро — ЭВМ соединена внутренняя шина данных микропроцессора: с адресной шиной, шиной данных, дешифратором адреса памяти или дешифратором адреса устройства ввода-вывода. [7]
Регистр адреса памяти помещает этот адрес на адресную шину. Дешифратор адреса памяти декодирует этот адрес. Импульсный сигнал Чтение памяти сообщает о том, что необходимо вывести содержимое области 0004 на шину данных микро — ЭВМ. Данные ( число 01) загружаются в младший байт регистра адреса памяти по сигналу ф2 генератора тактовых импульсов микропроцессора. [8]
В процессе цикла выборки команды содержимое счетчика команд загружается в регистр адреса памяти. Дешифратор адреса памяти декодирует данные, поступающие по адресной шине. После поступления импульсного сигнала Чтение памяти команда LDA из области памяти 0000 помещается на шину данных микро — ЭВМ, а с этой шины записывается в регистр команд микропроцессора. [10]
Регистр адреса памяти задает второй байт первой команды, содержащий данные ОС. Дешифратор адреса памяти декодирует адрес данного байта, и по получении импульсного сигнала Чтение памяти данные ( число ОС) поступают на шину данных микро — ЭВМ. При выполнении команды LDA данные ( ОС) загружаются в аккумулятор. Это означает, что значение данных не равно 0, старший их разряд не равен 1, и переноса из старшего разряда при выполнении операции не произошло. [12]
В цикле выборки содержимое счетчика команд пересылается в регистр адреса памяти. Дешифратор адреса памяти декодирует адрес. При поступлении импульса Чтение памяти значение области 0000 подается на шину данных микро — ЭВМ. Так как происходит цикл выборки, это значение загружается в регистр команд. Устройство управления декодирует команду ЗАГРУЗКА АККУМУЛЯТОРА ПРЯМАЯ. [13]
Второй цикл фазы выполнения иллюстрирует рис. 7.16. Так как мы имеем в данном случае дело с 3-байтовой командой, регистр адреса памяти указывает на ячейку 0009, где находится третий байт команды перехода. Адрес декодируется дешифратором адреса памяти . При поступлении сигнала Чтение памяти содержимое ячейки 0009 ( число 03) выводится на шину данных и пересылается в младший байт счетчика команд. Выполнение программы на этом заканчивается. Являющееся ее результатом содержимое счетчика команд будет использовано в начале выполнения следующей команды. [14]
Устройство управления принуждает сейчас регистр адреса памяти указывать на область памяти 0002, в которой содержится третий байт команды ЗАГРУЗКА РЕГИСТРОВОЙ ПАРЫ НЕПОСРЕДСТВЕННАЯ. Из регистра адреса памяти этот адрес подается на адресную шину, и дешифратор адреса памяти его декодирует. [15]
Порядок байтов
В современной вычислительной технике и цифровых системах связи информация обычно представлена в виде последовательности байтов. В том случае, если число не может быть представлено одним байтом, имеет значение, в каком порядке байты записываются в памяти компьютера или передаются по линиям связи. Часто выбор порядка записи байтов произволен и определяется только соглашениями.
В общем случае, для представления числа M, большего 255 (здесь 255 = 2 8 − 1 — максимальное целое число, записываемое одним байтом), приходится использовать несколько байтов (n). При этом число M записывается в позиционной системе счисления по основанию 256:
M = ∑ i = 0 n − 1 A i ⋅ 256 i = A 0 ⋅ 256 0 + A 1 ⋅ 256 1 + A 2 ⋅ 256 2 + ⋯ + A n − 1 ⋅ 256 n − 1 .
Набор целых чисел A 0 , … , A n − 1 , каждое из которых лежит в интервале от 0 до 255, является последовательностью байтов, составляющих M. При этом A 0
называется младшим байтом, а A n − 1
— старшим байтом числа M.
Поскольку компьютер не адресует отдельных битов (их можно получать только через битовые поля), порядок битов в байте важен только при физической организации хранения и передачи данных, может отличаться от устройства к устройству и прикладному программисту обычно не нужен.
Содержание
- 1 Варианты записи
- 1.1 Порядок от старшего к младшему
- 1.2 Порядок от младшего к старшему
- 1.3 Переключаемый порядок
- 1.4 Смешанный порядок
- 1.5 Пример
- 2 Определение порядка байтов
- 3 Вещественные числа
- 4 Юникод
- 5 Проблемы совместимости и конверсии
- 6 Этимология названия
- 7 См. также
- 8 Примечания
- 9 Ссылки
Варианты записи [ править | править код ]
Порядок от старшего к младшему [ править | править код ]
Порядок от старшего к младшему (англ. big-endian — с большого конца): A n − 1 , … , A 0 . Этот порядок подобен привычному порядку записи (например арабскими цифрами) «слева-направо» , например, число сто двадцать три было бы записано при таком порядке как 123. В этом же порядке принято записывать байты в технической и учебной литературе, если другой порядок явно не обозначен.
Этот порядок является стандартным для протоколов TCP/IP, он используется в заголовках пакетов данных и во многих протоколах более высокого уровня, разработанных для использования поверх TCP/IP. Поэтому порядок байтов от старшего к младшему часто называют «сетевым порядком байтов» (англ. network byte order ). Этот порядок байтов используется процессорами IBM 360/370/390, SPARC, Motorola 68000 (отсюда третье название — порядок байтов Motorola, англ. Motorola byte order ).
При таком порядке байтов удобно проводить сравнение строк (можно сравнивать их целочисленными полями-частями большей разрядности, каждое из которых содержит несколько символов сразу).
Порядок байтов от старшего к младшему применяется также во многих форматах файлов — например, PNG, FLV, EBML, JPEG.
Порядок от младшего к старшему [ править | править код ]
Порядок от младшего к старшему (англ. little-endian — с малого конца): A 0 , … , A n − 1
Это обратный привычному порядку записи чисел арабскими цифрами, например, число сто двадцать три было бы записано при таком порядке как 321. Иными словами этот порядок подобен правилу записи «справа-налево».
Этот порядок записи принят в памяти персональных компьютеров с процессорами архитектуры x86, в связи с чем иногда его называют интеловским порядком байтов (по названию компании-создателя архитектуры x86). Современные процессоры x86 позволяют работать с одно-, двух-, четырёх- и восьмибайтовыми операндами. В таком порядке следования байтов очень удобно то, что при увеличении размера (количества байтов) операнда, значение его первого байта неизменно: 3210 → 3210’0000. При порядке от старшего к младшему значение изменилось бы, например: 0123 → 0000’0123;
Кроме x86, такой порядок байтов применяется в архитектурах VAX (отсюда ещё одно название англ. VAX byte order [1] ), DEC Alpha и многих других.
Также порядок «от младшего к старшему» применяется в USB, PCI, таблице разделов GUID, он рекомендован FidoNet. Но в целом соглашение little-endian поддерживают меньше кросс-платформенных протоколов и форматов данных, чем big-endian.
Переключаемый порядок [ править | править код ]
Многие процессоры могут работать и в порядке «от младшего к старшему», и в обратном, например, ARM (по умолчанию — little endian), PowerPC (кроме PowerPC 970), DEC Alpha, MIPS, PA-RISC и IA-64. Обычно порядок байтов выбирается программно во время инициализации операционной системы, но может быть выбран и аппаратно перемычками на материнской плате. В этом случае правильнее говорить о порядке байтов на уровне операционной системы. Переключаемый порядок байтов иногда называют англ. bi-endian .
Смешанный порядок [ править | править код ]
Смешанный (комбинированный, гибридный) порядок байтов (англ. middle-endian) иногда используется при работе с числами, длина которых превышает машинное слово. Число представляется последовательностью машинных слов, которые записываются в формате, естественном для данной архитектуры, но сами машинные слова следуют в обратном порядке.
В процессорах VAX и ARM используется смешанное представление для длинных вещественных чисел.
Пример [ править | править код ]
Далее приведён пример, в котором описывается размещение 4-байтового числа в ОЗУ ЭВМ, доступ к которому может производиться и как к 32-разрядному слову, и побайтно.
Все числа записаны в 16-ричной системе счисления.
Представление | A 1 ∗ 1000000 16 + B 2 ∗ 10000 16 + C 3 ∗ 100 16 + D 4 ∗ 1 16 = A 1 B 2 C 3 D 4 | 161 ∗ 16 10 6 + 178 ∗ 16 10 4 + 195 ∗ 16 10 2 + 212 10 = 2712847316 10 | |
Порядок от младшего к старшему | (little-endian) | D 4 16 , C 3 16 , B 2 16 , A 1 16 | 212 10 , 195 10 , 178 10 , 161 10 |
Порядок от старшего к младшему | (big-endian) | A 1 16 , B 2 16 , C 3 16 , D 4 16 | 161 10 , 178 10 , 195 10 , 212 10 |
Порядок, принятый в PDP-11 | (PDP-endian) | B 2 16 , A 1 16 , D 4 16 , C 3 16 | 178 10 , 161 10 , 212 10 , 195 10 |
Определение порядка байтов [ править | править код ]
Порядок байтов (endianness) в конкретной машине можно определить с помощью программы на языке Си (testbyteorder.c):
Результаты запуска на big-endian машине (SPARC):
Результаты запуска на little-endian машине (x86):
Вещественные числа [ править | править код ]
Хранение вещественных чисел также может зависеть от порядка байтов. Так, на x86 используются форматы IEEE 754 со знаком и порядком числа в старших байтах.
Юникод [ править | править код ]
Если Юникод записан в формате UTF-16 или UTF-32, то порядок байтов уже существеннен. Одним из способов обозначения порядка байтов в UNICOD-текстах является постановка в начале специального символа BOM (byte order mark, маркер последовательности байтов, U+FEFF) — «перевёрнутый» вариант этого символа (U+FFFE) не существует и не допускается в текстах.
Символ U+FEFF изображается в UTF-16 последовательностью байтов 0xFE 0xFF (big-endian) или 0xFF 0xFE (little-endian), а в UTF-32 — последовательностью 0x00 0x00 0xFE 0xFF (big-endian) или 0xFF 0xFE 0x00 0x00 (little-endian).
Проблемы совместимости и конверсии [ править | править код ]
Запись многобайтового числа из памяти компьютера в файл или передача по сети требует соблюдения соглашений о том, какой из байтов передается первым. Прямая запись в том порядке, в котором байты расположены в ячейках памяти, приводит как к проблемам при переносе приложения с платформы на платформу, так и в межсистемном сетевом обмене данными.
Для преобразования между сетевым порядком байтов (англ. network byte order ), который всегда big-endian, и порядком байтов, использующимся на машине (англ. host byte order ), стандарт POSIX предусматривает функции htonl() , htons() , ntohl() , ntohs() :
- uint32_t htonl(uint32_t hostlong); — конвертирует 32-битную беззнаковую величину из локального порядка байтов в сетевой;
- uint16_t htons(uint16_t hostshort); — конвертирует 16-битную беззнаковую величину из локального порядка байтов в сетевой;
- uint32_t ntohl(uint32_t netlong); — конвертирует 32-битную беззнаковую величину из сетевого порядка байтов в локальный;
- uint16_t ntohs(uint16_t netshort); — конвертирует 16-битную беззнаковую величину из сетевого порядка байтов в локальный.
В случае совпадения текущего порядка байтов и сетевого функции отработают как «пустые» — то есть порядок байтов не поменяется. Стандарт также допускает, чтобы эти функции были реализованы в виде макросов.
Существует много языков и библиотек со средствами конвертации в оба основных порядка байтов и обратно.
Ядро Linux: le16_to_cpu(), cpu_to_be32(), cpu_to_le16p(), и так далее;
Ядро FreeBSD: htobe16(), le32toh(), и так далее;