Ответ 1
Вспомните в "плохих" днях MS-DOS, что некоторые функции ОС контролировались путем установки высоких грызков и низких полубайтов в регистре и выполнение Interupt xx. Например, Int 21 получил доступ ко многим функциям файла. Вы бы установили высокий грызть в качестве номера диска - у кого будет более 15 дисков? Низкий полубайт как запрошенная функция на этом диске и т.д.
Здесь - это старый код CPAN, который использует пакет, как вы описали, чтобы установить регистры для выполнения системного вызова MS-DOS.
Blech!!! Я вообще не пропустил MS-DOS...
- Изменить
Вот конкретный исходный код: Скачать Perl 5.00402 для DOS ЗДЕСЬ, распаковать,
В файле Opcode.pm и Opcode.pl вы видите здесь unpack("h*",$_[0]);
:
sub opset_to_hex ($) {
return "(invalid opset)" unless verify_opset($_[0]);
unpack("h*",$_[0]);
}
Я не выполнял весь код до конца, но мое подозрение заключается в том, чтобы восстановить информацию из системного вызова MS-DOS...
В perlport для Perl 5.8-8 у вас есть эти предлагаемые тесты для цели цели:
Различные ЦП хранят целые числа и числа с плавающей запятой в разных заказы (называемые endianness) и ширины (32-битная и 64-битная составляющая наиболее распространенный сегодня). Это влияет на ваши программы, когда они пытаются передать числа в двоичном формате от одной архитектуры процессора до другой, обычно либо "живут" через сетевое соединение, либо путем хранения номера для вторичного хранилища, такие как файл диска или лента.
Конфликтующие заказы на хранение делают полный беспорядок из числа. Если little-endian host (Intel, VAX) хранит
0x12345678
(305419896
в десятичный), хост-носитель большого размера (Motorola, Sparc, PA) читает его как0x78563412
(2018915346
в десятичной системе). Альфа и MIPS могут быть: Digital/Compaq использует/использует их в режиме little-endian; SGI/Cray использует их в режиме больших чисел. Чтобы избежать этой проблемы в сети (сокет) соединения используют форматыpack
иunpack
n
иn
, "сетевые" заказы. Они гарантированно переносятся.Начиная с perl 5.8.5, вы также можете использовать модификаторы
>
и<
для принудительного байт-ордера большого или малого конца. Это полезно, если вы хотите например, хранить целые числа со знаком или 64-битные целые числа.Вы можете исследовать сущность вашей платформы, распаковывая структура данных, упакованная в собственном формате, например:
print unpack("h*", pack("s2", 1, 2)), "\n"; # '10002000' on e.g. Intel x86 or Alpha 21064 in little-endian mode # '00100020' on e.g. Motorola 68040
Если вам нужно различать конечные архитектуры, вы можете использовать либо из переменных, заданных так:
$is_big_endian = unpack("h*", pack("s", 1)) =~ /01/; $is_little_endian = unpack("h*", pack("s", 1)) =~ /^1/;
Разные ширины могут вызывать усечение даже между платформами равных порядок байт. Платформа более короткой ширины теряет верхние части номер. Нет хорошего решения этой проблемы, кроме как избежать перенос или сохранение необработанных двоичных чисел.
Можно обойти обе эти проблемы двумя способами. Или переносить и хранить номера всегда в текстовом формате, а не сырые бинарные, или же использовать модули типа
Data::Dumper
(включенные в стандартное распределение по Perl 5.005) иStorable
(включено как of perl 5.8). Сохранение всех данных в виде текста значительно упрощает дело.v-строки переносимы только до
v2147483647
(0x7FFFFFFF
), это насколько EBCDIC или, точнее, UTF-EBCDIC.
Кажется, что unpack("h*",...)
используется чаще, чем pack("h*",...)
. Я заметил, что return qq'unpack("F", pack("h*", "$hex"))';
используется в Deparse.pm
, а IO-Compress
использует pack("*h",...)
в Perl 5.12
Если вам нужны дополнительные примеры, вот Список поиска кода Google. Вы можете видеть, что pack|unpack("h*"...)
встречается довольно редко и в основном связано с определением окончательности платформы...