为什么中断0x2A在x64中不起作用?

时间:2012-11-16 04:41:16

标签: windows delphi assembly

我使用此代码来获取系统时间:

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中获得系统中断,任何人都可以修复它吗?

1 个答案:

答案 0 :(得分:12)

此行为与OS处理器体系结构无关。 0x2A中断允许访问未记录的函数KiGetTickCount ,但这仅适用于Windows XP,从Windows vista开始,您可以使用{{3}函数获取自系统启动以来经过的毫秒数,也可以使用GetTickCount64 WMI类和LastBootUpTime属性。

顺便说一句,如果你需要测量一个小于49.7天的时间框架,你可以使用Win32_OperatingSystem功能。

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

更新

似乎KiGetTickCount函数仅在32位版本的Windows上通过中断0x2A接口公开。

这是使用内核调试器在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

现在是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