Una característica indocumentada de multiplicación y división en procesadores x86

A partir del procesador 80286, Intel ha mantenido una compatibilidad ascendente total en el conjunto de instrucciones. Es decir, si algunas de las instrucciones del procesador dan tal o cual resultado en 8086, entonces el resultado será exactamente el mismo en procesadores posteriores (ahora no consideraremos errores como la división incorrecta en Pentium I).





¿Pero es? ¡Que pregunta! Después de todo, si no se conservó la compatibilidad, los programas antiguos no podrían ejecutarse y aún puede sentirse nostálgico en cualquier computadora ejecutando Norton Commander o Tetris. Sin embargo, no todo es tan simple ... A partir del 8080, los procesadores Intel tienen un registro de banderas, cuyo estado está determinado por el resultado del último comando de cálculo de datos. Todas las banderas se han descrito en él durante mucho tiempo y su comportamiento está estrictamente fijado. Salvo dos excepciones.





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. En las operaciones de división, todos los procesadores Intel establecen el mismo bit de paridad (pero no coincide con la paridad de los bits de los últimos bytes de la división y el resultado del módulo).





  4. El bit AF después de la división se establece en 0 en los procesadores Intel, excepto para las familias Yonah y versiones anteriores.





  5. AMD después de la división establece AF = 1 y PF = 0.





La tabla de prueba completa se puede descargar





Si alguien tiene acceso a procesadores que no han sido probados, participe.





UPD Poco a poco agrego las pruebas de procesador enviadas. Los detalles están en los comentarios.








All Articles