Вот тело GetSystemTimeAsFileTime (это под XP SP2): 7C8017E7 push ebp 7C8017E8 mov ebp,esp 7C8017EA mov eax,[7FFE0018] 7C8017EF mov edx,dword ptr ds:[7FFE0014h] 7C8017F5 cmp eax,dword ptr ds:[7FFE001Ch] 7C8017FB jne 7C8017EA 7C8017FD mov ecx,dword ptr [ebp+8] 7C801800 mov dword ptr [ecx],edx 7C801802 mov dword ptr [ecx+4],eax 7C801805 pop ebp 7C801806 ret 4 Так вот как видно ф-ция читает время по адресам [7FFE0018] и [7FFE0014h], потом сравнивает старшее слово с тем что по адресу [7FFE001Ch] и если не равно, то цикл повторяется, иначе время прочитано. Вопросса три: 1) что за сравнения и зачем? 2) как получить сии адреса под любой операционкой (из ряда NTшных ядер) с минимумом затрат? 3) можно ли использовать это тело скажем под 2к без изменений, кроме перечисленных адресов?
win 2000 sp4 Код (Text): 793A72E5 >/$ A1 1800FE7F MOV EAX,DWORD PTR DS:[7FFE0018] 793A72EA |. 8B15 1400FE7F MOV EDX,DWORD PTR DS:[7FFE0014] 793A72F0 |. 3B05 1C00FE7F CMP EAX,DWORD PTR DS:[7FFE001C] 793A72F6 |.^ 75 ED JNZ SHORT kernel32.GetSystemTimeAsFileTime 793A72F8 |. 8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4] 793A72FC |. 8911 MOV DWORD PTR DS:[ECX],EDX 793A72FE |. 8941 04 MOV DWORD PTR DS:[ECX+4],EAX 793A7301 \. C2 0400 RETN 4 даже адреса можно не менять
lkd> dt /r1 nt!_KUSER_SHARED_DATA +0x000 TickCountLow : Uint4B +0x004 TickCountMultiplier : Uint4B +0x008 InterruptTime : _KSYSTEM_TIME +0x000 LowPart : Uint4B +0x004 High1Time : Int4B +0x008 High2Time : Int4B +0x014 SystemTime : _KSYSTEM_TIME +0x000 LowPart : Uint4B +0x004 High1Time : Int4B +0x008 High2Time : Int4B .... nt!KeUpdateSystemTime: ... 80544254 89531c mov dword ptr [ebx+1Ch],edx ;High2Time 80544257 894b14 mov dword ptr [ebx+14h],ecx ;LowPart 8054425a 895318 mov dword ptr [ebx+18h],edx ;High1Time ... 0:000> u kernel32!GetSystemTimeAsFileTime Lc kernel32!GetSystemTimeAsFileTime: mov edi,edi push ebp mov ebp,esp mov eax,dword ptr [SharedUserData+0x18] ;High1Time mov edx,dword ptr [SharedUserData+0x14] ;LowPart cmp eax,dword ptr [SharedUserData+0x1c] ;High1Time==High2Time jne kernel32!GetSystemTimeAsFileTime+0x5 mov ecx,dword ptr [ebp+8] mov dword ptr [ecx],edx ;dwLowDateTime mov dword ptr [ecx+4],eax ;dwHighDateTime pop ebp ret 4 Если по русски, дата хранится в двух числах High и Low, чтение их обоих неатомарная оперция, блокировать дорого. Ядерный код который обновляет значения обновляет High2,Low а потом High1. GetSystemTimeAsFileTime читает в обратном порядке и при несовпадении перечитывает. Адрес SharedUserData вроде постоянен (http://uninformed.org/index.cgi?v=2&a=2&p=16) P.S. в реактосе это реализовано видимо неправильно: http://www.reactos.org/generated/doxygen/df/d0e/ntoskrnl_2ke_2arm_2time_8c-source.html#l00037 http://www.reactos.org/generated/doxygen/d1/d5a/dll_2win32_2kernel32_2misc_2time_8c.html#cbdb4ddfd0c4082c95f89a0e6f693c69