Hi
I Programming a little with FindFirstFile and FindNextFile now have i a problem with my counter.
I add a counter and push and pop ecx to the stack.
Use i the register ecx works my counter not correct replace i this to esi or other register,
works this correct why?
I have look in the kernel32.dll (win7) with Ollydbg at 75EAA977
And see the ecx if not pushed or poped !!
If this an Bug of FindNextFile by Windows 7?
Here is my code
Scan proc uses edi ecx
LOCAL buffer[MAX_PATH]:BYTE
LOCAL wfd:WIN32_FIND_DATA
LOCAL hwfd:DWORD
invoke lstrcpy,addr buffer,addr hPath
invoke lstrcat,addr buffer,CTEXT ("/*.*")
invoke FindFirstFile,addr buffer,addr wfd
.if eax!=INVALID_HANDLE_VALUE
mov hwfd,eax
xor ecx,ecx
.while (eax!=0) && (ecx<3)
lea edi,wfd.cFileName
invoke AddItem,edi,1
inc ecx
invoke FindNextFile,hwfd,addr wfd
.endw
;No more matches, close handle
invoke FindClose,hwfd
.endif
ret
Scan endp
Greets,
the api calls probably destroy the ecx register.. push it before the api call and pop it after...
and i think...
xor ecx,ecx ; ecx is zero here, making the code below useless as ecx will be zero and definately less than 3...
.while (eax!=0) && (ecx<3)
is wrong..
xor ecx,ecx ; ecx is zero here, making the code below useless as ecx will be zero and definately less than 3...
.while (eax!=0) && (ecx<3)
This is fine, it's just FindNextFile trashing ecx. Most win API functions only preserve ebx/esi/edi I believe.
@evlncrn8
xor ecx,ecx ; This fill ecx with zero
.while (eax!=0) && (ecx<3) ;if ecx less than 3 inc ecx . if ecx greater then jmp out of the loop
...
..
inc ecx
.endw
Yes this api destroy the ecx register ,and use ecx without push ecx in to stack or pop ecx from stack
preservation rule
only EBX EDI ESI are returned without changes.
Your proc must do the same thing (unproc PROC uses ebx esi edi machin:DWORD)
Quotepreservation rule
only EBX EDI ESI are returned without changes.
oh - and EBP
oh - and the direction flag
@ToutEnMasm
I understand not correct what you mean with it :'(
Quote from: dedndave on October 13, 2010, 05:26:28 PM
oh - and the direction flag
That would be worth a test - try calling some APIs with the flag set :bg
ragdog,
Why to use ECX ? Why not EBX ?
Replace ECX by EBX and try again. Is there a bug ?
Rui
Quote from: ragdog on October 13, 2010, 05:57:57 PM
@ToutEnMasm
I understand not correct what you mean with it :'(
He means: when you call an API function, it may change the values in registers <EAX>, ECX, EDX, but not in EBX, ESI, EDI - so, if you need the values of eax/ecx/edx, you must save them yourself outside of the function call.
This is standard for (almost) all API functions.
@RuiLoureiro
Yes i can use edi ebx or anything
I use always ecx as counter and have found this problem
This is a rule of thumb Mnemonics and i coding with it
EAX =Accumulator
EBX = Base
ECX = Counter
EDX =Destination
ESI = Source index
EDI = Destination index
EBP =Base Pointer
ESP =Stack Pointer
EIP =Instructions pointer
ESP = Stack pointer
Thanks Tedd
Quoteyou must save them yourself outside of the function call.
You mean before i call a api push my register to the stack?
Greets
Quote from: jj2007 on October 13, 2010, 08:49:03 PM
Quote from: dedndave on October 13, 2010, 05:26:28 PM
oh - and the direction flag
That would be worth a test - try calling some APIs with the flag set :bg
I'd guess the notion isn't so much of preserving the direction flag as assuming it will, and should always be, cleared (string operations increment the index registers.) So, if a function internally sets it, it will 'restore' the value by clearing it again, even if it was in fact set to begin with.
Quote from: ragdog on October 13, 2010, 10:12:25 PM
You mean before i call a api push my register to the stack?
Yes - but usually only for eax, ecx, edx.
Also, don't worry so much about the 'definitions' for the registers - they are all general purpose (except for a few cases) and can be used in any way.
Thanks
i don't suggest saving and restoring the eflags register
only - if you set the direction flag, be sure and clear it before you call an API
and clear it when your function is complete
in fact, i had a case where sometimes the direction flag needed to be set and sometimes it didn't
i pushed the eflags register and popped it into a general register, then tested the state of the DF
if it was clear, i did nothing - if it was set, i cleared it with CLD
that seemed to work better than simply pushing and popping the eflags register
POPFD, CLD, and STD are slow instructions
pushfd
pop eax
test ah,4
jz @F
cld
@@:
Interesting technique, Dave. On my Celeron, it is slower than a simple cld, though:
Intel(R) Celeron(R) M CPU 420 @ 1.60GHz (SSE3)
127 cycles for 10*pushfd+cld
72 cycles for 10*simple cld
that's true, of course, if the flag is set
try it for a 50/50 set/not set :bg