One undocumented feature of multiplication and division on x86 processors

Starting with the 80286 processor, Intel has maintained full bottom-up compatibility in the instruction set. That is, if any of the processor instructions gives such and such a result on the 8086, then on later processors the result will be exactly the same (now we will not consider errors such as incorrect division in Pentium I).





But is it? What a question! After all, if compatibility was not preserved, then old programs could not run, and you can still feel nostalgic on any computer by running Norton Commander or Tetris. However, not everything is so simple ... Starting with the 8080, Intel processors have a flags register, the state of which is determined by the result of the last data calculation command. All flags have been described in it for a long time and their behavior is strictly fixed. Except for two 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. On divide operations, all Intel processors set the parity bit the same (but it does not match the parity of the bits of the last bytes of the division and modulo result).





  4. AF bit after division is set to 0 in Intel processors, except for Yonah families and earlier.





  5. AMD after division sets AF = 1 and PF = 0.





The complete test table can be downloaded





If anyone has access to processors that have not been tested, please take part.





UPD Little by little I add the submitted processor tests. Details are in the comments.








All Articles