The MASM Forum Archive 2004 to 2012

Project Support Forums => HLA Forum => Topic started by: indiocolifa on September 14, 2006, 07:21:27 PM

Title: MOVSB lockup
Post by: indiocolifa on September 14, 2006, 07:21:27 PM
I'm trying to load up an array with current system processes.

The result is page fault at first iteration.

First I allocate space for 100 PROCESSENTRY32 structures:


/* load processes in array */
mem.alloc ( @size(w.PROCESSENTRY32)*PROCLIST_INITSIZE);
mov (eax, pe32a_ptr);
LoadProcessList (hSnapshot, pe32a_ptr);


The LOADPROCESSLIST procedure is as follows:


//--------------------------------------------------------------------
// load a list of processes in an array of win32 PROCESSENTRY32
// structures
//--------------------------------------------------------------------
procedure LoadProcessList ( hSnap:DWORD; pe32a_ptr:DWORD); @nodisplay;
const
    PE32SZ := @size(w.PROCESSENTRY32);
static
pe32:w.PROCESSENTRY32;

begin LoadProcessList;
     
push (eax);
push (ebx);
push (ecx);
push (edx); // count number of processes
push (esi);
push (edi);

mov (PE32SZ, pe32.dwSize);
w.Process32First (hSnap, &pe32);
cmp (eax, 0);
je  NOP32FIRST;

/* Loop through all processes storing process info
   in pe32a_ptr array */
xor (edx, edx);
cld ();

next_process:
intmul (PE32SZ, edx, ebx);
mov (pe32a_ptr[ebx], edi);
mov (&pe32, esi);
mov (PE32SZ, ecx);
rep.movsb();
inc (edx);
stdout.put (pe32a_ptr[ebx]);
w.Process32Next (hSnap, &pe32);
cmp (eax, 0);
je  exitp;
jmp next_process;

NOP32FIRST:
stdout.put ("(!) No process information available.",nl);

exitp:
    pop (edi);
    pop (esi);
    pop (edx);
    pop (ecx);
    pop (ebx);
pop (eax);

end LoadProcessList;



Any help? I'm using the rep.movsb properly?

thank you very much
Title: Re: MOVSB lockup
Post by: Sevag.K on September 15, 2006, 02:36:52 AM
mov (pe32a_ptr[ebx], edi);  // edi = value at pe32a_ptr[ebx]

You want address of pe32a_ptr[ebx]

try:

lea ( edi, pe32a_ptr[ebx] );  // edi = address at pe32a_ptr[ebx]

Also, there is no guarantee that Windows will preserve EDX through API calls.  You may want to preserve that.
ESI, EDI and EBX are pretty safe through API calls, but even then some buggy versions of Windows may fail to preserve those on rare occasions.

Once you work that out, you can significantly speed up the routine by using rep.movsd.  Since we know @size (w.PROCESSENTRY32)  >4 and dword-aligned, we can shift ecx to the right by 2 (effectively ecx = ecx/4) and use rep.movsd.

Title: Re: MOVSB lockup
Post by: indiocolifa on September 15, 2006, 07:44:35 PM
with LEA instruction gives me access violation.

Maybe I'm passing the pointer (p32a_ptr) from mem.alloc badly?
Title: Re: MOVSB lockup
Post by: Sevag.K on September 15, 2006, 11:51:57 PM
That's probably it.  Seems like your procedure argument is by value.
Here's the way to get the proper address:

Use pass-by-reference in the procedure argument
procedure LoadProcessList ( hSnap:DWORD; var pe32a_ptr:DWORD); @nodisplay;

Then use a register to reference the address.

intmul (PE32SZ, edx, ebx);
mov (pe32a_ptr, edi);  // edi = address of memory
add (ebx, edi);             // edi = required offset
mov (&pe32, esi);
mov (PE32SZ, ecx);
...