Une fonctionnalité non documentée de multiplication et de division sur les processeurs x86

À partir du processeur 80286, Intel a maintenu une compatibilité ascendante complète dans le jeu d'instructions. Autrement dit, si certaines des instructions du processeur donnent tel ou tel résultat sur 8086, alors le résultat sera exactement le même sur les processeurs ultérieurs (maintenant nous ne considérerons pas les erreurs telles que la division incorrecte dans Pentium I).





Mais est-ce vrai? Quelle question! Après tout, si la compatibilité n'était pas préservée, les anciens programmes ne pourraient pas fonctionner et vous pouvez toujours vous sentir nostalgique sur n'importe quel ordinateur en exécutant Norton Commander ou Tetris. Cependant, tout n'est pas si simple ... A partir du 8080, les processeurs Intel ont un registre de drapeau dont l'état est déterminé par le résultat de la dernière commande de calcul de données. Tous les drapeaux y sont décrits depuis longtemps et leur comportement est strictement fixé. Sauf pour deux exceptions.





AF – . . 8- 8080 . 16- x86 – ? Intel – AF . 8080 . 16- AF !





, - ! AF PF !





:





#include <iostream>
#include <iomanip> 

int main()
{
    using namespace std;
    const int min_i = -20, max_i = 50,min_j=-10, max_j = 50;
    short int i, j, k, pf;
    cout << "Name;i;j;Result;AF;PF;Calculated parity\n";
    
    for (i = min_i; i < max_i; i++) {
        for (j = min_j; j < max_j; j++) {
            __asm {
                mov ax, i
                mov dx, j
                imul dx
                pushf
                pop ax
                mov k, ax
            }
            pf = i * j;  pf = ((pf >> 7) ^ (pf >> 6) ^ (pf >> 5) ^ (pf >> 4) ^ (pf >> 3) ^ (pf >> 2) ^ (pf >> 1) ^ pf ^ 1) & 1;
            cout << "Mul ;" << setw(4) << i << "; " << setw(4) << j << "; " << setw(4) << i * j << "; " << ((k & 0x10) ? "1" : "0") << "; " << ((k & 0x04) ? "1" : "0") << "; " << pf <<"\n";

        }
    }
        
    for (i = min_i; i < max_i; i++) {
        for (j = min_j; j < max_j; j++) {
            if (j == 0) continue;
            __asm {
                mov ax, i
                mov cx, j
                cwd
                idiv cx
                pushf                
                pop ax
                mov k, ax
            }
            pf = i / j;  pf = ((pf >> 7) ^ (pf >> 6) ^ (pf >> 5) ^ (pf >> 4) ^ (pf >> 3) ^ (pf >> 2) ^ (pf >> 1) ^ pf ^ 1) & 1;
            std::cout << "Div ;" << setw(4) << i << "; " << setw(4) << j << "; " << setw(4) << i / j << "; " << ((k & 0x10) ? "1" : "0") << "; " << ((k & 0x04) ? "1" : "0") << "; " << pf << "\n";
        }
    }
}


      
      



AF PF . ( ) .





16 . :





















Wolfdale





Sandy Bridge





Coffee Lake





AMD





















Pentium Dual-Core E6600





Core i5-2300





Xeon E-2278G





AMD Ryzen 7 2700





i





j





Result





Cal parity





AF





PF





AF





PF





AF





PF





AF





PF





-20





-10





200





0





0





1





0





0





0





0





0





1





-20





-9





180





1





0





1





0





1





0





1





0





1





-20





-8





160





1





0





1





0





1





0





1





0





1





-20





-7





140





0





0





0





0





0





0





0





0





0





-20





-6





120





1





0





0





0





1





0





1





0





0





-20





-5





100





0





0





1





0





0





0





0





0





1





-20





-4





80





1





0





1





0





1





0





1





0





1





-20





-3





60





1





0





0





0





1





0





1





0





0





-20





-2





40





1





0





1





0





1





0





1





0





1





-20





-1





20





1





0





0





0





1





0





1





0





0





-20





0





0





1





1





0





0





1





0





1





1





0





-20





1





-20





0





1





1





0





0





0





0





1





1





-20





2





-40





1





0





0





0





1





0





1





0





0





-20





3





-60





0





0





1





0





0





0





0





0





1





-20





4





-80





0





0





1





0





0





0





0





0





1





-20





5





-100





1





0





0





0





1





0





1





0





0





-20





6





-120





1





0





1





0





1





0





1





0





1





-20





7





-140





1





0





0





0





1





0





1





0





0





-20





8





-160





1





0





0





0





1





0





1





0





0





-20





9





-180





0





0





1





0





0





0





0





0





1





-20





10





-200





0





0





1





0





0





0





0





0





1





-20





11





-220





1





0





0





0





1





0





1





0





0





-20





12





-240





0





0





0





0





0





0





0





0





0





-20





13





-260





1





0





1





0





1





0





1





0





1





-20





14





-280





1





0





0





0





1





0





1





0





0





-20





15





-300





1





0





1





0





1





0





1





0





1





-20





16





-320





1





1





1





0





1





0





1





1





1





-20





17





-340





1





1





0





0





1





0





1





1





0





-20





18





-360





0





0





0





0





0





0





0





0





0





-20





19





-380





1





0





1





0





1





0





1





0





1





-20





20





-400





0





0





1





0





0





0





0





0





1





-20





21





-420





1





0





0





0





1





0





1





0





0





-20





22





-440





1





0





1





0





1





0





1





0





1





-20





23





-460





0





0





0





0





0





0





0





0





0





-20





24





-480





0





0





0





0





0





0





0





0





0





-20





25





-500





1





0





1





0





1





0





1





0





1





-20





26





-520





0





0





1





0





0





0





0





0





1





-20





27





-540





1





0





0





0





1





0





1





0





0





-20





28





-560





0





0





0





0





0





0





0





0





0





-20





29





-580





0





0





1





0





0





0





0





0





1





-20





30





-600





0





0





0





0





0





0





0





0





0





-20





31





-620





0





0





1





0





0





0





0





0





1





-20





32





-640





0





1





1





0





0





0





0





1





1





-20





33





-660





1





1





0





0





1





0





1





1





0





-20





34





-680





0





0





1





0





0





0





0





0





1





-20





35





-700





1





0





0





0





1





0





1





0





0





-20





36





-720





1





0





0





0





1





0





1





0





0





-20





37





-740





0





0





1





0





0





0





0





0





1





-20





38





-760





0





0





0





0





0





0





0





0





0





-20





39





-780





0





0





1





0





0





0





0





0





1





-20





40





-800





0





0





1





0





0





0





0





0





1





-20





41





-820





1





0





0





0





1





0





1





0





0





-20





42





-840





1





0





0





0





1





0





1





0





0





-20





43





-860





0





0





1





0





0





0





0





0





1





-20





44





-880





1





0





1





0





1





0





1





0





1





-20





45





-900





0





0





0





0





0





0





0





0





0





-20





46





-920





0





0





1





0





0





0





0





0





1





-20





47





-940





0





0





0





0





0





0





0





0





0





-20





48





-960





0





1





0





0





0





0





0





1





0





-20





49





-980





0





1





1





0





0





0





0





1





1

























Yonah





Conroe





Coffee Lake





AMD





















Core Duo T2450





Core 2 Duo E6750





Xeon_E-2278G





AMD Ryzen 7 2700





i





j





Result





Calc parity





AF





PF





AF





PF





AF





PF





AF





PF





-20





-10





2





0





0





1





0





1





0





1





1





0





-20





-9





2





0





0





0





0





0





0





0





1





0





-20





-8





2





0





0





0





0





0





0





0





1





0





-20





-7





2





0





0





1





0





1





0





1





1





0





-20





-6





3





1





0





1





0





1





0





1





1





0





-20





-5





4





0





0





0





0





0





0





0





1





0





-20





-4





5





1





0





1





0





1





0





1





1





0





-20





-3





6





1





0





0





0





0





0





0





1





0





-20





-2





10





1





0





0





0





0





0





0





1





0





-20





-1





20





1





0





1





0





1





0





1





1





0





-20





1





-20





0





0





0





0





0





0





0





1





0





-20





2





-10





1





0





0





0





0





0





0





1





0





-20





3





-6





1





0





1





0





1





0





1





1





0





-20





4





-5





0





0





0





0





0





0





0





1





0





-20





5





-4





1





0





1





0





1





0





1





1





0





-20





6





-3





0





0





1





0





1





0





1





1





0





-20





7





-2





0





0





0





0





0





0





0





1





0





-20





8





-2





0





0





0





0





0





0





0





1





0





-20





9





-2





0





0





1





0





1





0





1





1





0





-20





10





-2





0





0





1





0





1





0





1





1





0





-20





11





-1





1





0





0





0





0





0





0





1





0





-20





12





-1





1





0





1





0





1





0





1





1





0





-20





13





-1





1





0





0





0





0





0





0





1





0





-20





14





-1





1





0





0





0





0





0





0





1





0





-20





15





-1





1





0





1





0





1





0





1





1





0





-20





16





-1





1





1





0





0





0





0





0





1





0





-20





17





-1





1





0





1





0





1





0





1





1





0





-20





18





-1





1





0





1





0





1





0





1





1





0





-20





19





-1





1





0





0





0





0





0





0





1





0





-20





20





-1





1





0





1





0





1





0





1





1





0





-20





21





0





1





0





0





0





0





0





0





1





0





-20





22





0





1





0





0





0





0





0





0





1





0





-20





23





0





1





0





1





0





1





0





1





1





0





-20





24





0





1





0





1





0





1





0





1





1





0





-20





25





0





1





0





0





0





0





0





0





1





0





-20





26





0





1





0





0





0





0





0





0





1





0





-20





27





0





1





0





1





0





1





0





1





1





0





-20





28





0





1





0





0





0





0





0





0





1





0





-20





29





0





1





0





1





0





1





0





1





1





0





-20





30





0





1





0





1





0





1





0





1





1





0





-20





31





0





1





0





0





0





0





0





0





1





0





-20





32





0





1





1





0





0





0





0





0





1





0





-20





33





0





1





0





1





0





1





0





1





1





0





-20





34





0





1





0





1





0





1





0





1





1





0





-20





35





0





1





0





0





0





0





0





0





1





0





-20





36





0





1





0





1





0





1





0





1





1





0





-20





37





0





1





0





0





0





0





0





0





1





0





-20





38





0





1





0





0





0





0





0





0





1





0





-20





39





0





1





0





1





0





1





0





1





1





0





-20





40





0





1





0





1





0





1





0





1





1





0





-20





41





0





1





0





0





0





0





0





0





1





0





-20





42





0





1





0





0





0





0





0





0





1





0





-20





43





0





1





0





1





0





1





0





1





1





0





-20





44





0





1





0





0





0





0





0





0





1





0





-20





45





0





1





0





1





0





1





0





1





1





0





-20





46





0





1





0





1





0





1





0





1





1





0





-20





47





0





1





0





0





0





0





0





0





1





0





-20





48





0





1





1





1





0





1





0





1





1





0





-20





49





0





1





0





0





0





0





0





0





1





0









, :





  1. Intel ( Wolfdale – «» , Sandy Bridge – «» (Nehalem )). «» AF 0, PF – ( ). «» .





  2. AMD , «» Intel.





  3. Lors des opérations de division, tous les processeurs Intel définissent le bit de parité de la même manière (mais il ne correspond pas à la parité des bits des derniers octets de la division et du résultat modulo).





  4. Le bit AF après la division est défini sur 0 dans les processeurs Intel, sauf pour les familles Yonah et antérieures.





  5. AMD après la division définit AF = 1 et PF = 0.





Le tableau de test complet peut être téléchargé





Si quelqu'un a accès à des processeurs qui n'ont pas été testés, veuillez participer.





UPD J'ajoute petit à petit les tests de processeurs soumis. Les détails sont dans les commentaires.








All Articles