在糟糕的“旧日子”中,MS-DOS控制着某些操作系统功能,通过设置寄存器上的高位和低位并执行中断xx来完成。例如,Int 21访问了许多文件功能。您会将高位设置为驱动器号--谁会拥有超过15个驱动器??将低位设置为该驱动器上请求的功能,等等。
这里是一些旧的CPAN代码,使用pack正如您所描述的设置寄存器以执行MS-DOS系统调用。
呕吐!!! 我一点也不想念MS-DOS...
--编辑
以下是具体源代码:下载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中,您可以对目标的字节顺序进行以下建议测试:
Different CPUs store integers and floating point numbers in different
orders (called endianness) and widths (32-bit and 64-bit being the
most common today). This affects your programs when they attempt to transfer
numbers in binary format from one CPU architecture to another,
usually either “live” via network connection, or by storing the
numbers to secondary storage such as a disk file or tape.
Conflicting storage orders make utter mess out of the numbers. If a
little-endian host (Intel, VAX) stores 0x12345678
(305419896
in
decimal), a big-endian host (Motorola, Sparc, PA) reads it as
0x78563412
(2018915346
in decimal). Alpha and MIPS can be either:
Digital/Compaq used/uses them in little-endian mode; SGI/Cray uses
them in big-endian mode. To avoid this problem in network (socket)
connections use the pack
and unpack
formats n
and N
, the
“network” orders. These are guaranteed to be portable.
As of perl 5.8.5, you can also use the >
and <
modifiers
to force big- or little-endian byte-order. This is useful if you want
to store signed integers or 64-bit integers, for example.
You can explore the endianness of your platform by unpacking a
data structure packed in native format such as:
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
If you need to distinguish between endian architectures you could use
either of the variables set like so:
$is_big_endian = unpack("h*", pack("s", 1)) =~ /01/;
$is_little_endian = unpack("h*", pack("s", 1)) =~ /^1/;
Differing widths can cause truncation even between platforms of equal
endianness. The platform of shorter width loses the upper parts of the
number. There is no good solution for this problem except to avoid
transferring or storing raw binary numbers.
One can circumnavigate both these problems in two ways. Either
transfer and store numbers always in text format, instead of raw
binary, or else consider using modules like Data::Dumper
(included in
the standard distribution as of Perl 5.005) and Storable
(included as
of perl 5.8). Keeping all data as text significantly simplifies matters.
The v-strings are portable only up to v2147483647
(0x7FFFFFFF
), that's
how far EBCDIC, or more precisely UTF-EBCDIC will go.
看起来 unpack("h*",...)
比 pack("h*",...)
更常用。我注意到在 Deparse.pm
中使用了 return qq'unpack("F", pack("h*", "$hex"))';
,而在 Perl 5.12 中 IO-Compress
使用了 pack("*h",...)
。
如果您想要更多的例子,这里有一个 Google Code Search list。您可以看到 pack|unpack("h*"...)
相对较少,大多数与确定平台字节顺序有关...
pack
,但它没有与之一起使用h
或H
,只有s
和c
。 - cjm