2012-11-16 26 views
5

Ho UES questo codice per ottenere sistema il tempo:Perché interrompere 0x2A non funziona in x64?

procedure GetSystemUpTime(var Hour, Minute : integer); 

function GetSysTime : dword; 
    asm 
    int $2a 
    end; 
begin 
    Hour := GetSysTime() div 3600000; 
    Minute := GetSysTime() mod 3600000 div 60000; 
end; 

procedure TForm1.Button1Click(Sender : TObject); 
var 
    H, M : integer; 
begin 
    GetSystemUpTime(H, M); 
    Label1.Caption := IntToStr(H) + ':' + IntToStr(M); 
end; 

provo in win8 x86 e XP x86 funziona, ma non riescono a win7 x64 con l'errore:

enter image description here

mi chiedo come ottenere interruzione del sistema in x64, qualcuno può risolverlo?

risposta

12

Questo comportamento non è correlato all'architettura del processore del sistema operativo. L'interruzione 0x2A dà accesso alla funzione non documentata KiGetTickCount , ma funziona solo fino a Windows XP, a partire da Windows Vista è possibile utilizzare la funzione GetTickCount64 per ottenere i millisecondi che sono trascorsi da quando è stato avviato il sistema, inoltre è possibile utilizzare il Win32_OperatingSystem Classe WMI e la proprietà LastBootUpTime.

BTW, Se è necessario misurare un intervallo di tempo minore di 49,7 giorni, è possibile utilizzare la funzione GetTickCount.

procedure GetSystemUpTime(var Hour, Minute : integer); 
var 
LTicks : DWORD; 
begin 
    LTicks := GetTickCount(); 
    Hour := LTicks div 3600000; 
    Minute := LTicks mod 3600000 div 60000; 
end; 

UPDATE

Sembra che la funzione KiGetTickCount è esposto tramite l'interfaccia di interruzione 0x2A solo sulle versioni a 32 bit di Windows.

Questo è il risultato del dump IDT (Tabella descrittore di interrupt) su x86 Windows che utilizza Kernel Debugger.

00: 805421b0 nt!KiTrap00 
01: f620a4f6 ati2mtag+0x1774F6 
02: Task Selector = 0x0058 
03: f620a59c ati2mtag+0x17759C 
04: 805428c0 nt!KiTrap04 
05: 80542a20 nt!KiTrap05 
06: 80542b94 nt!KiTrap06 
07: 8054320c nt!KiTrap07 
08: Task Selector = 0x0050 
09: 80543610 nt!KiTrap09 
0a: 80543730 nt!KiTrap0A 
0b: 80543870 nt!KiTrap0B 
0c: 80543ad0 nt!KiTrap0C 
0d: 80543dbc nt!KiTrap0D 
0e: 805444b8 nt!KiTrap0E 
0f: 805447f0 nt!KiTrap0F 
10: 80544910 nt!KiTrap10 
11: 80544a4c nt!KiTrap11 
12: Task Selector = 0×00A0 
13: 80544bb4 nt!KiTrap13 
14: 805447f0 nt!KiTrap0F 
15: 805447f0 nt!KiTrap0F 
16: 805447f0 nt!KiTrap0F 
17: 805447f0 nt!KiTrap0F 
18: 805447f0 nt!KiTrap0F 
19: 805447f0 nt!KiTrap0F 
1a: 805447f0 nt!KiTrap0F 
1b: 805447f0 nt!KiTrap0F 
1c: 805447f0 nt!KiTrap0F 
1d: 805447f0 nt!KiTrap0F 
1e: 805447f0 nt!KiTrap0F 
1f: 806e710c hal!HalpApicSpuriousService 
20: 00000000 
21: 00000000 
22: 00000000 
23: 00000000 
24: 00000000 
25: 00000000 
26: 00000000 
27: 00000000 
28: 00000000 
29: 00000000 
>>2a: 805419de nt!KiGetTickCount<< 
2b: 80541ae0 nt!KiCallbackReturn 
2c: 80541c90 nt!KiSetLowWaitHighThread 
2d: 8054261c nt!KiDebugService 
2e: 80541461 nt!KiSystemService 
2f: 805447f0 nt!KiTrap0F 
30: 80540b20 nt!KiUnexpectedInterrupt0 
31: 80540b2a nt!KiUnexpectedInterrupt1 
32: 80540b34 nt!KiUnexpectedInterrupt2 
33: 80540b3e nt!KiUnexpectedInterrupt3 
34: 80540b48 nt!KiUnexpectedInterrupt4 
35: 80540b52 nt!KiUnexpectedInterrupt5 
36: 80540b5c nt!KiUnexpectedInterrupt6 

ed ora in x64

00: fffff80001865180 nt!KiDivideErrorFault 
01: fffff80001865240 nt!KiDebugTrapOrFault 
02: fffff80001865380 nt!KiNmiInterrupt Stack = 0xFFFFFA60005F5D40 
03: fffff800018656c0 nt!KiBreakpointTrap 
04: fffff80001865780 nt!KiOverflowTrap 
05: fffff80001865840 nt!KiBoundFault 
06: fffff80001865900 nt!KiInvalidOpcodeFault 
07: fffff80001865ac0 nt!KiNpxNotAvailableFault 
08: fffff80001865b80 nt!KiDoubleFaultAbort Stack = 0xFFFFFA60005F1D40 
09: fffff80001865c40 nt!KiNpxSegmentOverrunAbort 
0a: fffff80001865d00 nt!KiInvalidTssFault 
0b: fffff80001865dc0 nt!KiSegmentNotPresentFault 
0c: fffff80001865ec0 nt!KiStackFault 
0d: fffff80001865fc0 nt!KiGeneralProtectionFault 
0e: fffff800018660c0 nt!KiPageFault 
10: fffff80001866400 nt!KiFloatingErrorFault 
11: fffff80001866540 nt!KiAlignmentFault 
12: fffff80001866600 nt!KiMcheckAbort Stack = 0xFFFFFA60005F3D40 
13: fffff80001866940 nt!KiXmmException 
1f: fffff80001895290 nt!KiApcInterrupt 
2c: fffff80001866ac0 nt!KiRaiseAssertion 
2d: fffff80001866b80 nt!KiDebugServiceTrap 
2f: fffff800018aeb60 nt!KiDpcInterrupt 
+0

Grazie per la risposta! – Hanlin

+3

Hai copiato il bug nel codice OP - immagina un cambio di orario da h: 59: 59.999 a (hh + 1): 00: 00.000 tra le due chiamate a 'GetTickCount()'. – mghie

+0

@mghie riparato ora – RRUZ