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

标签 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 中获得系统中断,有人可以修复它吗?

最佳答案

此行为与操作系统处理器架构无关。 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;

更新

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

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

关于windows - 为什么中断 0x2A 在 x64 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13410546/

相关文章:

delphi,对复制操作使用react或执行粘贴

delphi - 根据拖动区域动态调整控件大小

assembly - 将整数转换为字符串汇编 8086 tasm

windows - 带有特殊字符的 Lazarus ListBox SaveToFile 文件名

windows - 第一个 Windows 是用什么编写的?

delphi - 如何对 TComboBox 进行编程更改以与 LiveBindings 配合良好?

assembly - ARM汇编中str的解释

c - 这个shellcode又让人头疼

windows - 这些 RubyInstaller 2.4 组件有什么作用?

c - 我们如何在命令行开发环境中编写程序?