Ci ho messo tutta la mattina a capirlo. Avevo scorciato, a suo tempo, delle istruzioni che l'assembler interno poteva rappresentare con operandi di 8 bit quando implicavano un registro a cui veniva applicato un operando immediato sufficientemente piccolo. Sicche` avevo tradotto, ad esempio:
TEST EAX, 0xFFcon una piu` breve
TEST AL, 0xFFche tanto e` uguale, ai fini dei flag che imposta: nella fattispecie, se tra gli 8 bit meno significativi di EAX ce n'e` almeno uno impostato a 1, il risultato e` non-zero. Fin qui tutto bene, il problema e` che m'ero scordato di verificare che il registro in questione fosse uno dei quattro che hanno una parte bassa a 8 bit (EAX ha AL, EBX ha BL, ECX ha CL, EDX ha DL), e avevo allegramente esteso l'ottimizzazione anche a ESI, EDI, ESP, EBP, che non hanno sottoregistri a 8 bit. Sicche` stamani l'assembler interno stava traducendo:
if r has oddBites(che significa "se r ha impostati i bit che compongono il valore immediato 3", cioe` se r/4 da` un resto, cioe` se r non e` multiplo di 4) con la sequenza in linguaggio macchina:
F6C603con quella stava chiedendo, provocando un crash che non mi spiegavo, al microprocessore "testa i bit del valore 3 nel sottoregistro a 8 bit di ESI". E siccome il sottoregistro a 8 bit di ESI non esiste, chissa` cosa capiva; secondo me si chiedeva "EH?! BOH!" e pero` non crashava in quel punto, provocava un crash per via del risultato sbagliato di un arrotondamento per eccesso che allocava un blocco di heap un po' piu` piccolo del necessario. La sequenza corretta usa per forza la forma a 32 bit, cioe`:
F7C603000000e ora va bene, ma boja, c'e` voluta tutta la mattina a scoprire perche` cazzo non funzionava. L'istruzione sembrava corretta, infatti, nel sorgente L.in.oleum. Ma veniva assemblata male.

No, lo raccontavo perche` trovato divertente l'aver scoperto di aver usato un opcode a 8 bit su un registro di 32, come se facessi riferimento all'inesistente sottoregistro SI-L. Um... ma vedo che non diverte.