diff --git a/SystemInformation.cxx b/SystemInformation.cxx
index 8041a02fbd7da53516ca3bf001949471365784ee..13889b22db48376184c739c038dbbcefc9b1b6d1 100644
--- a/SystemInformation.cxx
+++ b/SystemInformation.cxx
@@ -173,6 +173,69 @@ typedef struct rlimit ResourceLimitType;
 # endif
 #endif
 
+#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64)
+#define USE_ASM_INSTRUCTIONS 1
+#else
+#define USE_ASM_INSTRUCTIONS 0
+#endif
+
+#if USE_ASM_INSTRUCTIONS
+
+#define CPUID_AWARE_COMPILER
+#ifdef CPUID_AWARE_COMPILER
+#define CPUID_INSTRUCTION    cpuid
+#else
+#define CPUID_INSTRUCTION    _asm _emit 0x0f _asm _emit 0xa2
+#endif
+
+/**
+ * call CPUID instruction
+ *
+ * Will return false if the instruction failed.
+ */
+static bool call_cpuid(int select, int result[4])
+{
+  int tmp[4];
+  // Use SEH to determine CPUID presence
+  __try {
+    _asm {
+#ifdef CPUID_AWARE_COMPILER
+      ; we must push/pop the registers <<CPUID>> writes to, as the
+      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
+      ; these registers to change.
+      push eax
+      push ebx
+      push ecx
+      push edx
+#endif
+      ; <<CPUID>>
+      mov eax, select
+      CPUID_INSTRUCTION
+      mov tmp[0 * TYPE int], eax
+      mov tmp[1 * TYPE int], ebx
+      mov tmp[2 * TYPE int], ecx
+      mov tmp[3 * TYPE int], edx
+
+#ifdef CPUID_AWARE_COMPILER
+      pop edx
+      pop ecx
+      pop ebx
+      pop eax
+#endif
+      }
+    }
+  __except(1)
+    {
+    return false;
+    }
+
+  memcpy(result, tmp, sizeof(tmp));
+  // The cpuid instruction succeeded.
+  return true;
+}
+#endif
+
+
 namespace KWSYS_NAMESPACE
 {
 template<typename T>
@@ -695,24 +758,11 @@ void SystemInformation::RunMemoryCheck()
 // --------------------------------------------------------------
 // SystemInformationImplementation starts here
 
-#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64)
-#define USE_ASM_INSTRUCTIONS 1
-#else
-#define USE_ASM_INSTRUCTIONS 0
-#endif
-
 #define STORE_TLBCACHE_INFO(x,y)  x = (x < y) ? y : x
 #define TLBCACHE_INFO_UNITS      (15)
 #define CLASSICAL_CPU_FREQ_LOOP    10000000
 #define RDTSC_INSTRUCTION      _asm _emit 0x0f _asm _emit 0x31
 
-#define CPUID_AWARE_COMPILER
-#ifdef CPUID_AWARE_COMPILER
-  #define CPUID_INSTRUCTION    cpuid
-#else
-  #define CPUID_INSTRUCTION    _asm _emit 0x0f _asm _emit 0xa2
-#endif
-
 #define MMX_FEATURE            0x00000001
 #define MMX_PLUS_FEATURE       0x00000002
 #define SSE_FEATURE            0x00000004
@@ -1613,39 +1663,8 @@ void SystemInformationImplementation::Delay(unsigned int uiMS)
 bool SystemInformationImplementation::DoesCPUSupportCPUID()
 {
 #if USE_ASM_INSTRUCTIONS
-  // Use SEH to determine CPUID presence
-    __try {
-        _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-            mov eax, 0
-      CPUID_INSTRUCTION
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-        }
-    }
-  __except(1)
-    {
-    // Stop the class from trying to use CPUID again!
-    return false;
-    }
-
-  // The cpuid instruction succeeded.
-  return true;
-
+  int dummy[4];
+  return call_cpuid(0, dummy);
 #else
   // Assume no cpuid instruction.
   return false;
@@ -1656,56 +1675,26 @@ bool SystemInformationImplementation::DoesCPUSupportCPUID()
 bool SystemInformationImplementation::RetrieveCPUFeatures()
 {
 #if USE_ASM_INSTRUCTIONS
-  int localCPUFeatures = 0;
-  int localCPUAdvanced = 0;
-
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
-      ;        ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
-      ;        edx: CPU feature flags
-      mov eax,1
-      CPUID_INSTRUCTION
-      mov localCPUFeatures, edx
-      mov localCPUAdvanced, ebx
+  int cpuinfo[4] = { 0, 0, 0, 0 };
 
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1)
+  if (!call_cpuid(1, cpuinfo))
     {
     return false;
     }
 
   // Retrieve the features of CPU present.
-  this->Features.HasFPU =     ((localCPUFeatures & 0x00000001) != 0);    // FPU Present --> Bit 0
-  this->Features.HasTSC =     ((localCPUFeatures & 0x00000010) != 0);    // TSC Present --> Bit 4
-  this->Features.HasAPIC =    ((localCPUFeatures & 0x00000200) != 0);    // APIC Present --> Bit 9
-  this->Features.HasMTRR =    ((localCPUFeatures & 0x00001000) != 0);    // MTRR Present --> Bit 12
-  this->Features.HasCMOV =    ((localCPUFeatures & 0x00008000) != 0);    // CMOV Present --> Bit 15
-  this->Features.HasSerial =  ((localCPUFeatures & 0x00040000) != 0);    // Serial Present --> Bit 18
-  this->Features.HasACPI =    ((localCPUFeatures & 0x00400000) != 0);    // ACPI Capable --> Bit 22
-  this->Features.HasMMX =     ((localCPUFeatures & 0x00800000) != 0);    // MMX Present --> Bit 23
-  this->Features.HasSSE =     ((localCPUFeatures & 0x02000000) != 0);    // SSE Present --> Bit 25
-  this->Features.HasSSE2 =    ((localCPUFeatures & 0x04000000) != 0);    // SSE2 Present --> Bit 26
-  this->Features.HasThermal = ((localCPUFeatures & 0x20000000) != 0);    // Thermal Monitor Present --> Bit 29
-  this->Features.HasIA64 =    ((localCPUFeatures & 0x40000000) != 0);    // IA64 Present --> Bit 30
+  this->Features.HasFPU =     ((cpuinfo[3] & 0x00000001) != 0);    // FPU Present --> Bit 0
+  this->Features.HasTSC =     ((cpuinfo[3] & 0x00000010) != 0);    // TSC Present --> Bit 4
+  this->Features.HasAPIC =    ((cpuinfo[3] & 0x00000200) != 0);    // APIC Present --> Bit 9
+  this->Features.HasMTRR =    ((cpuinfo[3] & 0x00001000) != 0);    // MTRR Present --> Bit 12
+  this->Features.HasCMOV =    ((cpuinfo[3] & 0x00008000) != 0);    // CMOV Present --> Bit 15
+  this->Features.HasSerial =  ((cpuinfo[3] & 0x00040000) != 0);    // Serial Present --> Bit 18
+  this->Features.HasACPI =    ((cpuinfo[3] & 0x00400000) != 0);    // ACPI Capable --> Bit 22
+  this->Features.HasMMX =     ((cpuinfo[3] & 0x00800000) != 0);    // MMX Present --> Bit 23
+  this->Features.HasSSE =     ((cpuinfo[3] & 0x02000000) != 0);    // SSE Present --> Bit 25
+  this->Features.HasSSE2 =    ((cpuinfo[3] & 0x04000000) != 0);    // SSE2 Present --> Bit 26
+  this->Features.HasThermal = ((cpuinfo[3] & 0x20000000) != 0);    // Thermal Monitor Present --> Bit 29
+  this->Features.HasIA64 =    ((cpuinfo[3] & 0x40000000) != 0);    // IA64 Present --> Bit 30
 
   // Retrieve extended SSE capabilities if SSE is available.
   if (this->Features.HasSSE) {
@@ -1739,13 +1728,13 @@ bool SystemInformationImplementation::RetrieveCPUFeatures()
   // Retrieve Intel specific extended features.
   if (this->ChipManufacturer == Intel)
     {
-    this->Features.ExtendedFeatures.SupportsHyperthreading =  ((localCPUFeatures &  0x10000000) != 0);  // Intel specific: Hyperthreading --> Bit 28
-    this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = (this->Features.ExtendedFeatures.SupportsHyperthreading) ? ((localCPUAdvanced & 0x00FF0000) >> 16) : 1;
+    this->Features.ExtendedFeatures.SupportsHyperthreading =  ((cpuinfo[3] &  0x10000000) != 0);  // Intel specific: Hyperthreading --> Bit 28
+    this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = (this->Features.ExtendedFeatures.SupportsHyperthreading) ? ((cpuinfo[1] & 0x00FF0000) >> 16) : 1;
 
     if ((this->Features.ExtendedFeatures.SupportsHyperthreading) && (this->Features.HasAPIC))
       {
       // Retrieve APIC information if there is one present.
-      this->Features.ExtendedFeatures.APIC_ID = ((localCPUAdvanced & 0xFF000000) >> 24);
+      this->Features.ExtendedFeatures.APIC_ID = ((cpuinfo[1] & 0xFF000000) >> 24);
       }
     }
 
@@ -1783,70 +1772,40 @@ void SystemInformationImplementation::FindManufacturer(const kwsys_stl::string&
 bool SystemInformationImplementation::RetrieveCPUIdentity()
 {
 #if USE_ASM_INSTRUCTIONS
-  int localCPUVendor[3];
-  int localCPUSignature;
+  int localCPUVendor[4];
+  int localCPUSignature[4];
 
-  // Use assembly to detect CPUID information...
-  __try
+  if (!call_cpuid(0, localCPUVendor))
     {
-    _asm
-      {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 0 --> eax: maximum value of CPUID instruction.
-      ;        ebx: part 1 of 3; CPU signature.
-      ;        edx: part 2 of 3; CPU signature.
-      ;        ecx: part 3 of 3; CPU signature.
-      mov eax, 0
-      CPUID_INSTRUCTION
-      mov localCPUVendor[0 * TYPE int], ebx
-      mov localCPUVendor[1 * TYPE int], edx
-      mov localCPUVendor[2 * TYPE int], ecx
-
-      ; <<CPUID>>
-      ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
-      ;        ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
-      ;        edx: CPU feature flags
-      mov eax,1
-      CPUID_INSTRUCTION
-      mov localCPUSignature, eax
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
+    return false;
     }
-  }
-  __except(1)
+  if (!call_cpuid(1, localCPUSignature))
     {
     return false;
     }
 
   // Process the returned information.
+  //    ; eax = 0 --> eax: maximum value of CPUID instruction.
+  //    ;        ebx: part 1 of 3; CPU signature.
+  //    ;        edx: part 2 of 3; CPU signature.
+  //    ;        ecx: part 3 of 3; CPU signature.
   char vbuf[13];
-  memcpy (&(vbuf[0]), &(localCPUVendor[0]), sizeof (int));
-  memcpy (&(vbuf[4]), &(localCPUVendor[1]), sizeof (int));
+  memcpy (&(vbuf[0]), &(localCPUVendor[1]), sizeof (int));
+  memcpy (&(vbuf[4]), &(localCPUVendor[3]), sizeof (int));
   memcpy (&(vbuf[8]), &(localCPUVendor[2]), sizeof (int));
   vbuf[12] = '\0';
   this->ChipID.Vendor = vbuf;
 
   // Retrieve the family of CPU present.
-  this->ChipID.ExtendedFamily =    ((localCPUSignature & 0x0FF00000) >> 20);  // Bits 27..20 Used
-  this->ChipID.ExtendedModel =    ((localCPUSignature & 0x000F0000) >> 16);  // Bits 19..16 Used
-  this->ChipID.Type =        ((localCPUSignature & 0x0000F000) >> 12);  // Bits 15..12 Used
-  this->ChipID.Family =        ((localCPUSignature & 0x00000F00) >> 8);    // Bits 11..8 Used
-  this->ChipID.Model =        ((localCPUSignature & 0x000000F0) >> 4);    // Bits 7..4 Used
-  this->ChipID.Revision =      ((localCPUSignature & 0x0000000F) >> 0);    // Bits 3..0 Used
+  //    ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
+  //    ;        ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
+  //    ;        edx: CPU feature flags
+  this->ChipID.ExtendedFamily = ((localCPUSignature[0] & 0x0FF00000) >> 20);  // Bits 27..20 Used
+  this->ChipID.ExtendedModel =  ((localCPUSignature[0] & 0x000F0000) >> 16);  // Bits 19..16 Used
+  this->ChipID.Type =           ((localCPUSignature[0] & 0x0000F000) >> 12);  // Bits 15..12 Used
+  this->ChipID.Family =         ((localCPUSignature[0] & 0x00000F00) >> 8);    // Bits 11..8 Used
+  this->ChipID.Model =          ((localCPUSignature[0] & 0x000000F0) >> 4);    // Bits 7..4 Used
+  this->ChipID.Revision =       ((localCPUSignature[0] & 0x0000000F) >> 0);    // Bits 3..0 Used
 
   return true;
 
@@ -1866,41 +1825,7 @@ bool SystemInformationImplementation::RetrieveCPUCacheDetails()
   // Check to see if what we are about to do is supported...
   if (RetrieveCPUExtendedLevelSupport (0x80000005))
     {
-    // Use assembly to retrieve the L1 cache information ...
-    __try
-      {
-      _asm
-        {
-#ifdef CPUID_AWARE_COMPILER
-         ; we must push/pop the registers <<CPUID>> writes to, as the
-        ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-        ; these registers to change.
-        push eax
-        push ebx
-        push ecx
-        push edx
-#endif
-        ; <<CPUID>>
-        ; eax = 0x80000005 --> eax: L1 cache information - Part 1 of 4.
-        ;             ebx: L1 cache information - Part 2 of 4.
-        ;             edx: L1 cache information - Part 3 of 4.
-        ;              ecx: L1 cache information - Part 4 of 4.
-        mov eax, 0x80000005
-        CPUID_INSTRUCTION
-        mov L1Cache[0 * TYPE int], eax
-        mov L1Cache[1 * TYPE int], ebx
-        mov L1Cache[2 * TYPE int], ecx
-        mov L1Cache[3 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-        pop edx
-        pop ecx
-        pop ebx
-        pop eax
-#endif
-        }
-      }
-    __except(1)
+    if (!call_cpuid(0x80000005, L1Cache))
       {
       return false;
       }
@@ -1917,41 +1842,7 @@ bool SystemInformationImplementation::RetrieveCPUCacheDetails()
   // Check to see if what we are about to do is supported...
   if (RetrieveCPUExtendedLevelSupport (0x80000006))
     {
-    // Use assembly to retrieve the L2 cache information ...
-    __try
-      {
-      _asm
-        {
-#ifdef CPUID_AWARE_COMPILER
-         ; we must push/pop the registers <<CPUID>> writes to, as the
-        ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-        ; these registers to change.
-        push eax
-        push ebx
-        push ecx
-        push edx
-#endif
-        ; <<CPUID>>
-        ; eax = 0x80000006 --> eax: L2 cache information - Part 1 of 4.
-        ;             ebx: L2 cache information - Part 2 of 4.
-        ;             edx: L2 cache information - Part 3 of 4.
-        ;              ecx: L2 cache information - Part 4 of 4.
-        mov eax, 0x80000006
-        CPUID_INSTRUCTION
-        mov L2Cache[0 * TYPE int], eax
-        mov L2Cache[1 * TYPE int], ebx
-        mov L2Cache[2 * TYPE int], ecx
-        mov L2Cache[3 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-        pop edx
-        pop ecx
-        pop ebx
-        pop eax
-#endif
-        }
-      }
-    __except(1)
+    if (!call_cpuid(0x80000006, L2Cache))
       {
       return false;
       }
@@ -1985,39 +1876,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
 
 
   do {
-    // Use assembly to retrieve the L2 cache information ...
-    __try {
-      _asm {
-#ifdef CPUID_AWARE_COMPILER
-         ; we must push/pop the registers <<CPUID>> writes to, as the
-        ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-        ; these registers to change.
-        push eax
-        push ebx
-        push ecx
-        push edx
-#endif
-        ; <<CPUID>>
-        ; eax = 2 --> eax: TLB and cache information - Part 1 of 4.
-        ;        ebx: TLB and cache information - Part 2 of 4.
-        ;        ecx: TLB and cache information - Part 3 of 4.
-        ;        edx: TLB and cache information - Part 4 of 4.
-        mov eax, 2
-        CPUID_INSTRUCTION
-        mov TLBCacheData[0 * TYPE int], eax
-        mov TLBCacheData[1 * TYPE int], ebx
-        mov TLBCacheData[2 * TYPE int], ecx
-        mov TLBCacheData[3 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-        pop edx
-        pop ecx
-        pop ebx
-        pop eax
-#endif
-        }
-      }
-    __except(1)
+    if (!call_cpuid(2, TLBCacheData))
       {
       return false;
       }
@@ -2312,7 +2171,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUClockSpeed()
 /** */
 bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULevelToCheck)
 {
-  int MaxCPUExtendedLevel = 0;
+  int cpuinfo[4] = { 0, 0, 0, 0 };
 
   // The extended CPUID is supported by various vendors starting with the following CPU models:
   //
@@ -2356,34 +2215,7 @@ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULev
     }
 
 #if USE_ASM_INSTRUCTIONS
-
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 0x80000000 --> eax: maximum supported extended level
-      mov eax,0x80000000
-      CPUID_INSTRUCTION
-      mov MaxCPUExtendedLevel, eax
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1)
+  if (!call_cpuid(0x80000000, cpuinfo))
     {
     return false;
     }
@@ -2391,7 +2223,7 @@ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULev
 
   // Now we have to check the level wanted vs level returned...
   int nLevelWanted = (CPULevelToCheck & 0x7FFFFFFF);
-  int nLevelReturn = (MaxCPUExtendedLevel & 0x7FFFFFFF);
+  int nLevelReturn = (cpuinfo[0] & 0x7FFFFFFF);
 
   // Check to see if the level provided is supported...
   if (nLevelWanted > nLevelReturn)
@@ -2420,59 +2252,29 @@ bool SystemInformationImplementation::RetrieveExtendedCPUFeatures()
     }
 
 #if USE_ASM_INSTRUCTIONS
-  int localCPUExtendedFeatures = 0;
+  int localCPUExtendedFeatures[4] = { 0, 0, 0, 0 };
 
-  // Use assembly to detect CPUID information...
-  __try
-    {
-    _asm
-      {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 0x80000001 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
-      ;             ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
-      ;             edx: CPU feature flags
-      mov eax,0x80000001
-      CPUID_INSTRUCTION
-      mov localCPUExtendedFeatures, edx
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-      }
-    }
-  __except(1)
+  if (!call_cpuid(0x80000001, localCPUExtendedFeatures))
     {
     return false;
     }
 
   // Retrieve the extended features of CPU present.
-  this->Features.ExtendedFeatures.Has3DNow = ((localCPUExtendedFeatures & 0x80000000) != 0);  // 3DNow Present --> Bit 31.
-  this->Features.ExtendedFeatures.Has3DNowPlus = ((localCPUExtendedFeatures & 0x40000000) != 0);  // 3DNow+ Present -- > Bit 30.
-  this->Features.ExtendedFeatures.HasSSEMMX = ((localCPUExtendedFeatures & 0x00400000) != 0);  // SSE MMX Present --> Bit 22.
-  this->Features.ExtendedFeatures.SupportsMP = ((localCPUExtendedFeatures & 0x00080000) != 0);  // MP Capable -- > Bit 19.
+  this->Features.ExtendedFeatures.Has3DNow =     ((localCPUExtendedFeatures[3] & 0x80000000) != 0);  // 3DNow Present --> Bit 31.
+  this->Features.ExtendedFeatures.Has3DNowPlus = ((localCPUExtendedFeatures[3] & 0x40000000) != 0);  // 3DNow+ Present -- > Bit 30.
+  this->Features.ExtendedFeatures.HasSSEMMX =    ((localCPUExtendedFeatures[3] & 0x00400000) != 0);  // SSE MMX Present --> Bit 22.
+  this->Features.ExtendedFeatures.SupportsMP =   ((localCPUExtendedFeatures[3] & 0x00080000) != 0);  // MP Capable -- > Bit 19.
 
   // Retrieve AMD specific extended features.
   if (this->ChipManufacturer == AMD)
     {
-    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures &  0x00400000) != 0);  // AMD specific: MMX-SSE --> Bit 22
+    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures[3] & 0x00400000) != 0);  // AMD specific: MMX-SSE --> Bit 22
     }
 
   // Retrieve Cyrix specific extended features.
   if (this->ChipManufacturer == Cyrix)
     {
-    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures &  0x01000000) != 0);  // Cyrix specific: Extended MMX --> Bit 24
+    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures[3] & 0x01000000) != 0);  // Cyrix specific: Extended MMX --> Bit 24
     }
 
   return true;
@@ -2493,50 +2295,19 @@ bool SystemInformationImplementation::RetrieveProcessorSerialNumber()
     }
 
 #if USE_ASM_INSTRUCTIONS
-  int SerialNumber[3];
+  int SerialNumber[4];
 
-    // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: Transmeta only ?!?
-      ;        ecx: middle 32 bits are the processor signature bits
-      ;        edx: bottom 32 bits are the processor signature bits
-      mov eax, 3
-      CPUID_INSTRUCTION
-      mov SerialNumber[0 * TYPE int], ebx
-      mov SerialNumber[1 * TYPE int], ecx
-      mov SerialNumber[2 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1)
+  if (!call_cpuid(3, SerialNumber))
     {
     return false;
     }
 
   // Process the returned information.
+  //    ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: Transmeta only ?!?
+  //    ;        ecx: middle 32 bits are the processor signature bits
+  //    ;        edx: bottom 32 bits are the processor signature bits
   char sn[128];
   sprintf (sn, "%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x",
-       ((SerialNumber[0] & 0xff000000) >> 24),
-       ((SerialNumber[0] & 0x00ff0000) >> 16),
-       ((SerialNumber[0] & 0x0000ff00) >> 8),
-       ((SerialNumber[0] & 0x000000ff) >> 0),
        ((SerialNumber[1] & 0xff000000) >> 24),
        ((SerialNumber[1] & 0x00ff0000) >> 16),
        ((SerialNumber[1] & 0x0000ff00) >> 8),
@@ -2544,7 +2315,11 @@ bool SystemInformationImplementation::RetrieveProcessorSerialNumber()
        ((SerialNumber[2] & 0xff000000) >> 24),
        ((SerialNumber[2] & 0x00ff0000) >> 16),
        ((SerialNumber[2] & 0x0000ff00) >> 8),
-       ((SerialNumber[2] & 0x000000ff) >> 0));
+       ((SerialNumber[2] & 0x000000ff) >> 0),
+       ((SerialNumber[3] & 0xff000000) >> 24),
+       ((SerialNumber[3] & 0x00ff0000) >> 16),
+       ((SerialNumber[3] & 0x0000ff00) >> 8),
+       ((SerialNumber[3] & 0x000000ff) >> 0));
   this->ChipID.SerialNumber = sn;
   return true;
 
@@ -2567,44 +2342,17 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement()
     }
 
 #if USE_ASM_INSTRUCTIONS
-  int localCPUPowerManagement = 0;
-
+  int localCPUPowerManagement[4] = { 0, 0, 0, 0 };
 
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 0x80000007 --> edx: get processor power management
-      mov eax,0x80000007
-      CPUID_INSTRUCTION
-      mov localCPUPowerManagement, edx
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1)
+  if (!call_cpuid(0x80000007, localCPUPowerManagement))
     {
     return false;
     }
 
   // Check for the power management capabilities of the CPU.
-  this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode =  ((localCPUPowerManagement & 0x00000001) != 0);
-  this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID =    ((localCPUPowerManagement & 0x00000002) != 0);
-  this->Features.ExtendedFeatures.PowerManagement.HasVoltageID =    ((localCPUPowerManagement & 0x00000004) != 0);
+  this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode =  ((localCPUPowerManagement[3] & 0x00000001) != 0);
+  this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID =     ((localCPUPowerManagement[3] & 0x00000002) != 0);
+  this->Features.ExtendedFeatures.PowerManagement.HasVoltageID =       ((localCPUPowerManagement[3] & 0x00000004) != 0);
 
   return true;
 
@@ -2637,54 +2385,15 @@ bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
 #if USE_ASM_INSTRUCTIONS
   int CPUExtendedIdentity[12];
 
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 0x80000002 --> eax, ebx, ecx, edx: get processor name string (part 1)
-      mov eax,0x80000002
-      CPUID_INSTRUCTION
-      mov CPUExtendedIdentity[0 * TYPE int], eax
-      mov CPUExtendedIdentity[1 * TYPE int], ebx
-      mov CPUExtendedIdentity[2 * TYPE int], ecx
-      mov CPUExtendedIdentity[3 * TYPE int], edx
-
-      ; <<CPUID>>
-      ; eax = 0x80000003 --> eax, ebx, ecx, edx: get processor name string (part 2)
-      mov eax,0x80000003
-      CPUID_INSTRUCTION
-      mov CPUExtendedIdentity[4 * TYPE int], eax
-      mov CPUExtendedIdentity[5 * TYPE int], ebx
-      mov CPUExtendedIdentity[6 * TYPE int], ecx
-      mov CPUExtendedIdentity[7 * TYPE int], edx
-
-      ; <<CPUID>>
-      ; eax = 0x80000004 --> eax, ebx, ecx, edx: get processor name string (part 3)
-      mov eax,0x80000004
-      CPUID_INSTRUCTION
-      mov CPUExtendedIdentity[8 * TYPE int], eax
-      mov CPUExtendedIdentity[9 * TYPE int], ebx
-      mov CPUExtendedIdentity[10 * TYPE int], ecx
-      mov CPUExtendedIdentity[11 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
+  if (!call_cpuid(0x80000002, CPUExtendedIdentity))
+    {
+    return false;
     }
-  }
-  __except(1)
+  if (!call_cpuid(0x80000003, CPUExtendedIdentity + 4))
+    {
+    return false;
+    }
+  if (!call_cpuid(0x80000004, CPUExtendedIdentity + 8))
     {
     return false;
     }
@@ -3794,20 +3503,15 @@ unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void)
     }
   return static_cast<unsigned char>(cores_per_package);
 #else
-  unsigned int Regebx = 0;
+  int Regs[4] = { 0, 0, 0, 0 };
 #if USE_ASM_INSTRUCTIONS
   if (!this->IsHyperThreadingSupported())
     {
     return static_cast<unsigned char>(1);  // HT not supported
     }
-  __asm
-    {
-    mov eax, 1
-    cpuid
-    mov Regebx, ebx
-    }
+  call_cpuid(1, Regs);
 #endif
-  return static_cast<unsigned char> ((Regebx & NUM_LOGICAL_BITS) >> 16);
+  return static_cast<unsigned char> ((Regs[1] & NUM_LOGICAL_BITS) >> 16);
 #endif
 }
 
@@ -3816,39 +3520,29 @@ unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void)
 unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
 {
 #if USE_ASM_INSTRUCTIONS
-  unsigned int Regedx    = 0,
-             Regeax      = 0,
-             VendorId[3] = {0, 0, 0};
-  __try    // Verify cpuid instruction is supported
+  int Regs[4] = { 0, 0, 0, 0 },
+             VendorId[4] = { 0, 0, 0, 0 };
+  // Get vendor id string
+  if (!call_cpuid(0, VendorId))
     {
-      __asm
-      {
-        xor eax, eax          // call cpuid with eax = 0
-            cpuid                 // Get vendor id string
-        mov VendorId, ebx
-        mov VendorId + 4, edx
-        mov VendorId + 8, ecx
-
-        mov eax, 1            // call cpuid with eax = 1
-        cpuid
-        mov Regeax, eax      // eax contains family processor type
-        mov Regedx, edx      // edx has info about the availability of hyper-Threading
-      }
+    return false;
     }
-  __except (EXCEPTION_EXECUTE_HANDLER)
+  // eax contains family processor type
+  // edx has info about the availability of hyper-Threading
+  if (!call_cpuid(1, Regs))
     {
-    return(0);                   // cpuid is unavailable
+    return false;
     }
 
-  if (((Regeax & FAMILY_ID) == PENTIUM4_ID) || (Regeax & EXT_FAMILY_ID))
+  if (((Regs[0] & FAMILY_ID) == PENTIUM4_ID) || (Regs[0] & EXT_FAMILY_ID))
     {
-    if (VendorId[0] == 'uneG')
+    if (VendorId[1] == 'uneG')
       {
-      if (VendorId[1] == 'Ieni')
+      if (VendorId[3] == 'Ieni')
         {
         if (VendorId[2] == 'letn')
           {
-          return(Regedx & HT_BIT);    // Genuine Intel with hyper-Threading technology
+          return(Regs[3] & HT_BIT);    // Genuine Intel with hyper-Threading technology
           }
         }
       }
@@ -3862,22 +3556,17 @@ unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
 /** Return the APIC Id. Works only for windows. */
 unsigned char SystemInformationImplementation::GetAPICId()
 {
-  unsigned int Regebx = 0;
+  int Regs[4] = { 0, 0, 0, 0 };
 
 #if USE_ASM_INSTRUCTIONS
   if (!this->IsHyperThreadingSupported())
     {
     return static_cast<unsigned char>(-1);  // HT not supported
     } // Logical processor = 1
-  __asm
-    {
-    mov eax, 1
-    cpuid
-    mov Regebx, ebx
-    }
+  call_cpuid(1, Regs);
 #endif
 
-  return static_cast<unsigned char>((Regebx & INITIAL_APIC_ID_BITS) >> 24);
+  return static_cast<unsigned char>((Regs[1] & INITIAL_APIC_ID_BITS) >> 24);
 }