NeilPryde
Гость
|
|
« : 15-07-2003 11:13 » |
|
Я тут просматривал исходники, написанные не мною, и обнаружил, что в них используется функция Win API - ZeroMemory, для обнуления памяти. Хотелось бы знать есть какие-нибудь преимущества у такого метода перед memset(..., 0, ...) и нафиг вообще ее придумали?
|
|
|
Записан
|
|
|
|
Lex
|
|
« Ответ #1 : 15-07-2003 11:24 » |
|
Фиг его знает. ZeroMemory(), как и FillMemory() Win API функции. memset() из стандартных библиотек. про скорость работы каждой из функций ничего сказать не могу.
Из описаний в MSDN у меня сложилось такое впечатление, что эти функции вырасли для корректной работы с виртуальной памятью и большими блоками в 16-битный сисстемах. Сейчас особой проблемы с этим нет.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #2 : 15-07-2003 11:29 » |
|
Как бы тебе ответить? По мне так без разницы. Единственное- memset входит в стандарт C.
Вот тебе дизассемблерный листинг RtlZeroMemory 77f798ae 57 push edi 77f798af 8b7c2408 mov edi,[esp+0x8] 77f798b3 8b4c240c mov ecx,[esp+0xc] 77f798b7 33c0 xor eax,eax 77f798b9 fc cld 77f798ba 8bd1 mov edx,ecx 77f798bc 83e203 and edx,0x3 77f798bf c1e902 shr ecx,0x2 77f798c2 f3ab rep stosd 77f798c4 0bca or ecx,edx 77f798c6 7504 jnz ntdll!RtlZeroMemory+0x1e (77f798cc) 77f798c8 5f pop edi 77f798c9 c20800 ret 0x8 77f798cc f3aa rep stosb 77f798ce 5f pop edi 77f798cf c20800 ret 0x8
А вот memset
77f784d0 8b54240c mov edx,[esp+0xc] 77f784d4 8b4c2404 mov ecx,[esp+0x4] 77f784d8 85d2 test edx,edx 77f784da 7447 jz ntdll!memset+0x53 (77f78523) 77f784dc 33c0 xor eax,eax 77f784de 8a442408 mov al,[esp+0x8] 77f784e2 57 push edi 77f784e3 8bf9 mov edi,ecx 77f784e5 83fa04 cmp edx,0x4 77f784e8 722d jb ntdll!memset+0x47 (77f78517) 77f784ea f7d9 neg ecx 77f784ec 83e103 and ecx,0x3 77f784ef 7408 jz ntdll!memset+0x29 (77f784f9) 77f784f1 2bd1 sub edx,ecx 77f784f3 8807 mov [edi],al 77f784f5 47 inc edi 77f784f6 49 dec ecx 77f784f7 75fa jnz ntdll!memset+0x23 (77f784f3) 77f784f9 8bc8 mov ecx,eax 77f784fb c1e008 shl eax,0x8 77f784fe 03c1 add eax,ecx 77f78500 8bc8 mov ecx,eax 77f78502 c1e010 shl eax,0x10 77f78505 03c1 add eax,ecx 77f78507 8bca mov ecx,edx 77f78509 83e203 and edx,0x3 77f7850c c1e902 shr ecx,0x2 77f7850f 7406 jz ntdll!memset+0x47 (77f78517) 77f78511 f3ab rep stosd 77f78513 85d2 test edx,edx 77f78515 7406 jz ntdll!memset+0x4d (77f7851d) 77f78517 8807 mov [edi],al 77f78519 47 inc edi 77f7851a 4a dec edx 77f7851b 75fa jnz ntdll!memset+0x47 (77f78517) 77f7851d 8b442408 mov eax,[esp+0x8] 77f78521 5f pop edi 77f78522 c3 ret 77f78523 8b442404 mov eax,[esp+0x4] 77f78527 c3 ret
Сравнивай и выбирай что тебе нравится!
|
|
|
Записан
|
|
|
|
NeilPryde
Гость
|
|
« Ответ #3 : 15-07-2003 11:48 » |
|
2SlavaI: Исчерпывающий ответ! Да, стандарт это хорошо - повышается переносимость кода и прочие рулезы. По листингу так сразу и не скажешь что лучше, но в ZeroMemory - кода меньше.
|
|
|
Записан
|
|
|
|
|
Заглянувший
Гость
|
|
« Ответ #5 : 16-07-2003 13:18 » |
|
WINBASE.H #define ZeroMemory RtlZeroMemory
WINNT.H #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
и всё, те же яйца, только в профиль
|
|
|
Записан
|
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #6 : 16-07-2003 13:33 » |
|
WINBASE.H #define ZeroMemory RtlZeroMemory
WINNT.H #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
и всё, те же яйца, только в профиль Вобще то RtlZeroMemory в двух вариантах- один напрямую из ntdll экспортируется, при линковке приложение линкуется с kernel32.dll но там вот что 703 2BE RtlZeroMemory (forwarded to NTDLL.RtlZeroMemory) Второй сделан через приведенное тобой макроопределение.
|
|
|
Записан
|
|
|
|
Заглянувший
Гость
|
|
« Ответ #7 : 16-07-2003 13:45 » |
|
из kernell-а, насколько я знаю, вызывается если ты под ДДК сидишь. Она там даже где-то в wdm.h или ntddk.h есть. Ща просто под рукой нету для конкретной инфы, но это по-моему и не требуется - я про ZeroMemory() под ДДК не слышал.
|
|
|
Записан
|
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #8 : 16-07-2003 13:55 » |
|
из kernell-а, насколько я знаю, вызывается если ты под ДДК сидишь. Она там даже где-то в wdm.h или ntddk.h есть. Ща просто под рукой нету для конкретной инфы, но это по-моему и не требуется - я про ZeroMemory() под ДДК не слышал. Нет, не правильно. Надо различать режим пользователя и режим ядра. Эта ф-ция экспортируется из ntdll и там же полностью реализована без перехода в режим ядра- проверь, вызови ее явно из своей проги. Совпадение имен ф-ций в режиме ядра и в режиме пользователя имеет место, например memset экспортируется как ядром так и run time библиотекой режима пользователя, у ядра есть своя run time библиотека не связанная с библиотекой пользовательского режима. Я даже несмотря скажу что в wdm.h ее нет, она в ntddk, но это не та ф-ция о которой мы говорим.
|
|
|
Записан
|
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #9 : 16-07-2003 13:58 » |
|
Кстати вот тебе RtlZeroMemory из ядра, сравни с той что я приводил для user мода- они идентичны, просто одна сделана для юзер мода(находится в ntdll.dll, выполняется в 3 кольце защиты IA-32) другая для ядра(находится в ntoskrnl.exe и выполняется в 0 кольце защиты IA-32).
80512606 57 push edi 80512607 8b7c2408 mov edi,[esp+0x8] 8051260b 8b4c240c mov ecx,[esp+0xc] 8051260f 33c0 xor eax,eax 80512611 fc cld 80512612 8bd1 mov edx,ecx 80512614 83e203 and edx,0x3 80512617 c1e902 shr ecx,0x2 8051261a f3ab rep stosd 8051261c 0bca or ecx,edx 8051261e 7504 jnz nt!RtlZeroMemory+0x1e (80512624) 80512620 5f pop edi 80512621 c20800 ret 0x8 80512624 f3aa rep stosb 80512626 5f pop edi 80512627 c20800 ret 0x8
|
|
|
Записан
|
|
|
|
|