Um recurso não documentado de multiplicação e divisão em processadores x86

Começando com o processador 80286, a Intel manteve compatibilidade total de baixo para cima no conjunto de instruções. Ou seja, se algumas das instruções do processador fornecem tal e tal resultado no 8086, o resultado será exatamente o mesmo nos processadores posteriores (agora não consideraremos erros como divisão incorreta no Pentium I).





Mas é isso? Que pergunta! Afinal, se a compatibilidade não fosse preservada, os programas antigos não poderiam ser executados e você ainda pode sentir saudades de qualquer computador executando o Norton Commander ou Tetris. Porém, nem tudo é tão simples ... A partir do 8080, os processadores Intel possuem um registrador de flag, cujo estado é determinado pelo resultado do último comando de cálculo de dados. Todos os sinalizadores foram descritos nele por um longo tempo e seu comportamento é estritamente fixo. Exceto por duas exceções.





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. Nas operações de divisão, todos os processadores Intel definem o bit de paridade da mesma forma (mas não corresponde à paridade dos bits dos últimos bytes da divisão e do resultado do módulo).





  4. O bit AF após a divisão é definido como 0 nos processadores Intel, exceto para famílias Yonah e anteriores.





  5. A AMD após a divisão define AF = 1 e PF = 0.





A tabela de teste completa pode ser baixada





Se alguém tiver acesso a processadores que não foram testados, participe.





UPD Aos poucos, adiciono os testes de processador enviados. Os detalhes estão nos comentários.








All Articles