2012-11-16 22 views
5

我正餐這個代碼來獲得系統時間:爲什麼中斷0x2A在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; 

我測試它在win8 x86XP x86它的工作原理,但在win7 x64錯誤失敗:

enter image description here

我不知道怎麼弄系統在x64中斷,任何人都可以修復它?

回答

12

此行爲與OS處理器體系結構無關。 0x2A中斷可以訪問無證功能KiGetTickCount ,但直到Windows XP中, 這只是工作從Windows Vista開始,你可以使用GetTickCount64函數來獲取自系統啓動之後所經過的毫秒數,也可以使用Win32_OperatingSystem WMI類和LastBootUpTime屬性。

順便說一句,如果你需要測量一個小於49.7天的時間幀,你可以使用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

看來該KiGetTickCount功能通過中斷0x2A接口暴露僅在Windows的32位版本。

這是使用內核調試器在x86 Windows上轉儲IDT(中斷描述符表)的結果。

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 

,現在在64

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

謝謝您的回答! – Hanlin

+3

您複製了OP代碼中的錯誤 - 想象在兩次調用GetTickCount()之間,時間從hh:59:59.999改爲(hh + 1):00:00.000。 – mghie

+0

@mghie立即修復 – RRUZ

相關問題