回想MS-DOS 的糟糕“旧时代”,某些操作系统功能是通过在寄存器上设置高半字节和低半字节并执行中断 xx 来控制的。例如,Int 21 访问了许多文件函数。您会将高半字节设置为驱动器编号——谁将拥有超过 15 个驱动器?低半字节作为该驱动器上请求的功能等。
Here 是一些旧的 CPAN 代码,它使用您描述的 pack 来设置寄存器以执行 MS-DOS 系统调用。
白痴!!!我一点也不怀念 MS-DOS...
--编辑
这里是具体的源码:Download Perl 5.00402 for DOS HERE,解压,
在 Opcode.pm 和 Opcode.pl 文件中,您可以在此处看到 unpack("h*",$_[0]); 的使用:
sub opset_to_hex ($) {
return "(invalid opset)" unless verify_opset($_[0]);
unpack("h*",$_[0]);
}
我没有完全按照代码进行操作,但我怀疑这是为了从 MS-DOS 系统调用中恢复信息...
在 Perl 5.8-8 的 perlport 中,您有以下建议的目标字节序测试:
不同的 CPU 以不同的方式存储整数和浮点数
顺序(称为 endianness)和宽度(32 位和 64 位是
今天最常见)。这会在您尝试传输时影响您的程序
从一种 CPU 架构到另一种的二进制格式的数字,
通常要么通过网络连接“直播”,要么通过存储
数字到辅助存储,如磁盘文件或磁带。
冲突的存储订单使数字变得一团糟。如果一个
little-endian 主机 (Intel, VAX) 存储 0x12345678 (305419896 in
十进制),大端主机(摩托罗拉,Sparc,PA)将其读取为
0x78563412(十进制的2018915346)。 Alpha 和 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(包括在
perl 5.8)。将所有数据保存为文本可以显着简化问题。
v-strings 只能移植到v2147483647 (0x7FFFFFFF),也就是说
EBCDIC,或者更准确地说是 UTF-EBCDIC 会走多远。
似乎unpack("h*",...) 的使用频率高于pack("h*",...)。我确实注意到return qq'unpack("F", pack("h*", "$hex"))'; 用于Deparse.pm 和IO-Compress 在Perl 5.12 中使用pack("*h",...)
如果您想要更多示例,这里是Google Code Search list。您可以看到pack|unpack("h*"...) 相当罕见,主要与确定平台字节序有关...