Ricordare nei giorni brutti di MS-DOS che alcune funzioni del sistema operativo erano controllate impostando nibble alti e bassi nibbles su un registro ed eseguendo un'intervallo xx. Ad esempio, Int 21 ha avuto accesso a molte funzioni di file. Dovresti impostare il nibble alto come numero di unità - chi avrà più di 15 unità? Il basso nibble come funzione richiesta su tale unità, ecc.
Here è un vecchio codice CPAN che utilizza il pacchetto come descritto per impostare i registri per eseguire una chiamata di sistema MS-DOS.
Blech !!! Non mi manca di MS-DOS a tutti ...
--edit
Qui è specifico codice sorgente: Scarica Perl 5,00,402 mila per DOS HERE, decomprimere,
Nel file di Opcode.pm e Opcode .pl si vede l'uso di unpack("h*",$_[0]);
qui:
sub opset_to_hex ($) {
return "(invalid opset)" unless verify_opset($_[0]);
unpack("h*",$_[0]);
}
non ho seguito il codice tutto il percorso attraverso, ma il mio sospetto è questo è quello di recuperare informazioni da una chiamata di sistema MS-DOS ...
diversi interi negozi CPU e numeri in virgola mobile in diverse ordini (chiamati endianness) e larghezze (3: in perlport per Perl 5,8-8, ci sono queste prove per endianess del target suggerito 2-bit e 64-bit sono gli più comuni oggi). Ciò influisce sui programmi quando tentano di trasferire i numeri in formato binario da un'architettura CPU a un'altra, in genere "live" tramite connessione di rete o memorizzando i numeri nella memoria secondaria come un file disco o nastro.
Gli ordini di stoccaggio in conflitto fanno completamente casino dai numeri. Se un ospite little-endian (Intel, VAX) negozi 0x12345678
(305419896
in decimale), un big-endian host (Motorola, Sparc, PA) legge come 0x78563412
(2018915346
in decimale). Alpha e MIPS possono essere: Digital/Compaq utilizzato/li usa in modalità little-endian; SGI/Cray utilizza in modalità big-endian. Per evitare questo problema nelle connessioni di rete (socket) utilizzare i formati pack
e unpack
n
e N
, gli ordini di "rete" . Questi sono garantiti per essere portatili.
A partire dal Perl 5.8.5, è anche possibile utilizzare i >
e <
modificatori per forzare l'ordine dei byte big-o little-endian. Ciò è utile se si desidera che memorizzi interi con segno o interi a 64 bit, ad esempio.
È possibile esplorare l'endianness della piattaforma per l'estrazione, una struttura di dati confezionato in formato nativo quali:
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
Se è necessario distinguere tra le architetture endian si potrebbe usare uno dei variabili impostate come così:
$is_big_endian = unpack("h*", pack("s", 1)) =~ /01/;
$is_little_endian = unpack("h*", pack("s", 1)) =~ /^1/;
diverse larghezze possono causare il troncamento anche tra le piattaforme di uguale endianness. La piattaforma di larghezza ridotta perde le parti superiori del numero . Non esiste una buona soluzione per questo problema se non per evitare che trasferisca o memorizzi numeri binari non elaborati.
Uno può circumnavigare entrambi questi problemi in due modi. Sia trasferimento e memorizzare numeri sempre in formato testo, invece di greggio binario, oppure considerare l'utilizzo di moduli come Data::Dumper
(inclusi nel distribuzione standard di Perl 5.005) e Storable
(incluso come di Perl 5.8). Mantenere tutti i dati come testo semplifica notevolmente gli argomenti.
I v-string sono portatili solo fino al v2147483647
(0x7FFFFFFF
), che è quanto lontano EBCDIC, o più precisamente UTF-EBCDIC andrà.
Sembra che unpack("h*",...)
viene utilizzato più spesso di quanto pack("h*",...)
. Ho fatto notare che return qq'unpack("F", pack("h*", "$hex"))';
viene utilizzato in Deparse.pm
e IO-Compress
utilizza pack("*h",...)
in Perl 5.12
Se volete altri esempi, ecco un Google Code Search list. È possibile vedere che pack|unpack("h*"...)
è piuttosto raro e per lo più riguarda la determinazione della endianità della piattaforma ...
Questo codice usa' pack', ma non usa 'h' o' H' con esso, solo 's' e' c'. – cjm