Register | Login
Forum Index > RTL > MemUtils
Author Message
Pages: 1 2
0CodErr
Ziron Guru
(send private message)

Posts: 199
Topics: 37

Location:
[1449] MemUtils - posted: 2015-01-13 19:28:58
In memutils.zir i found memfill routine which use only "rep stosb". It no so fast. And i try write myself memfill.

I do the same way as in strutils.zir:
function strFill(char* buf; dword dwlen; char _ch)

Code:
/*
/    Fill block of memory with specified value
/    $buf -- Pointer to block of memory to fill
/    $len -- Value to be set
/    $ch_ -- Number of bytes to set to value
/    Copyright (c) 0CodErr, KolibriOS team
*/
procedure memFill(char* buf; dword len; char _ch) {
  uses edi;

  eax = 0;
  al = _ch;
  edx = len;
  edi = buf;
  ecx = eax;
  ah = al;
  ch = cl;
  ecx << 16;
  or eax, ecx;
  ecx = edx;
  ecx >> 2;
  and edx, 3;
  rep stosd;
  ecx = edx;
  rep stosb;

  return buf;
}


But when i get result executable in it was: Code:
memFill:
0x55                   push   ebp
0x8bec                 mov    ebp, esp
0x57                   push   edi
0x33c0                 xor    eax, eax
0x8a450d               mov    al, [ebp + 0dh]
0x8b550c               mov    edx, [ebp + 0ch]
0x8b7d08               mov    edi, [ebp + 08h]
0x8bc8                 mov    ecx, eax
0x8ae0                 mov    ah, al
0x8ae9                 mov    ch, cl
0xc1e110               shl    ecx, 10h
0x0bc1                 or     eax, ecx
0x8bca                 mov    ecx, edx
0xc1e902               shr    ecx, 02h
0x83e203               and    edx, 03h
0xf3ab                 rep stosd 
0x8bca                 mov    ecx, edx
0xf3aa                 rep stosb 
0x8b4508               mov    eax, [ebp + 08h]
0x5f                   pop    edi
0xc9                   leave  
0xc20900               ret    09h


As far as i understand
[ebp + 08h] -- buf
[ebp + 0ch] -- len

but len should be dword then 0ch + 04h = 10h

why we get Code:
mov    al, [ebp + 0dh]
?

hmm.. and also Code:
ret    09h


As i think before call byte converted to dword.
For example: Code:
char mychar[2] = ['p', 0];
char char1 = 0x61;

memFill(@mychar, 1, char1);
Result: Code:
0x33c0                 xor    eax, eax
0xa002204000           mov    al, byte ptr  [loc_00402002]
0x50                   push   eax
0x6a01                 push   01h
0x6800204000           push   402000h
0xe80c010000           call   memFill

Admin
Site Admin

avatar

(send private message)

Posts: 933
Topics: 55

Location:
OverHertz Studio
[1451] - posted: 2015-01-13 20:33:30
Seems this is an alignment problem which since rewriting from Ziron 1 to Ziron 2 i have not fixed smile ... I will add this to my checklist and have it fixed for next release.

Thanks for bringing this to my attention.

EDIT: This is fixed for next release.

Download Ziron
Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.
0CodErr
Ziron Guru
(send private message)

Posts: 199
Topics: 37

Location:
[1458] - posted: 2015-01-14 16:28:50
Ok, i tested this routine in Ziron 2.0.0.14.

I defined Code:
char buf1[32] = 'xxxxxxxxxxxxxx';
Then i do memFill and print contents of buffer after call memFill.

Seems that this not works: Code:
print(@buf1);
print(buf1);
Therefore i use _console_writeansi.

This code works fine: Code:
program PE32_CUI 'test';

#include 'win_def.zir';
#include 'console.zir';

/*
/    Fill block of memory with specified value
/    $buf -- Pointer to block of memory to fill
/    $len -- Value to be set
/    $ch_ -- Number of bytes to set to value
/    Copyright (c) 0CodErr, KolibriOS team
*/
procedure memFill(char* buf; dword len; char ch_) {
  uses edi;

  eax = 0;
  al = ch_;
  edx = len;
  edi = buf;
  ecx = eax;
  ah = al;
  ch = cl;
  ecx << 16;
  or eax, ecx;
  ecx = edx;
  ecx >> 2;
  and edx, 3;
  rep stosd;
  ecx = edx;
  rep stosb;

  return buf;
}

char buf1[32] = 'xxxxxxxxxxxxxx';

print('Buffer contents BEFORE memFill:  "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 0, ord('y'));
print('Buffer contents AFTER memFill 0: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 1, ord('y'));
print('Buffer contents AFTER memFill 1: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 2, ord('y'));
print('Buffer contents AFTER memFill 2: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 3, ord('y'));
print('Buffer contents AFTER memFill 3: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 4, ord('y'));
print('Buffer contents AFTER memFill 4: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 5, ord('y'));
print('Buffer contents AFTER memFill 5: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 6, ord('y'));
print('Buffer contents AFTER memFill 6: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 7, ord('y'));
print('Buffer contents AFTER memFill 7: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 8, ord('y'));
print('Buffer contents AFTER memFill 8: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 9, ord('y'));
print('Buffer contents AFTER memFill 9: "');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 10, ord('y'));
print('Buffer contents AFTER memFill 10:"');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 11, ord('y'));
print('Buffer contents AFTER memFill 11:"');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 12, ord('y'));
print('Buffer contents AFTER memFill 12:"');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 13, ord('y'));
print('Buffer contents AFTER memFill 13:"');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 14, ord('y'));
print('Buffer contents AFTER memFill 14:"');
_console_writeansi(@buf1); print('"\n');

memFill(@buf1, 15, ord('y'));
print('Buffer contents AFTER memFill 15:"');
_console_writeansi(@buf1); print('"\n');

wait_key();
ExitProcess(0);
I think that now we already can add this routine memFill into memutils.zir.
Admin
Site Admin

avatar

(send private message)

Posts: 933
Topics: 55

Location:
OverHertz Studio
[1460] - posted: 2015-01-14 18:41:44
This is because the print macro detects the address as a DWord/pointer.

Try this:

open includes/windows/win_console.zir

replace print macro with the following:

Code:
inline procedure print(;) {
  $temp = 0;
  $tt = 0;

  $repeat $argc:  
    push eax
    push ecx
    push edx
      
    $tt = tokentype($arg[$temp]);
      
    $if $tt == TOKEN_NUMBER:
      $if casttype($arg[$temp]) == int32:  
        _console_write_int32($arg[$temp]);
      $else
        _console_write_dword($arg[$temp]);
      $end;
    $elseif $tt == TOKEN_ANSISTRING:
      _console_writeansi($arg[$temp]);
    $elseif $tt == TOKEN_REGISTER:
      $if casttype($arg[$temp]) == char*:        
        _console_writeansi($arg[$temp]);
      $elseif casttype($arg[$temp]) == int32:        
        _console_write_int32($arg[$temp]);
      $else
        _console_write_dword($arg[$temp]);
      $end;
    $else
      $if casttype($arg[$temp]) == char*:        
        _console_writeansi($arg[$temp]);
      $elseif casttype($arg[$temp]) == int32:        
        _console_write_int32($arg[$temp]);
      $elseif casttype($arg[$temp]) == char:  
        _console_writeansi(@$arg[$temp]);
      $else
        _console_write_dword($arg[$temp]);
      $end;    
      
      //$error = 'Unknown parameter "'+$tt+'" passed to "print"';
      //$raise $tt;
    $end;    
    
    $temp = $temp + 1;

    pop edx
    pop ecx
    pop eax
  $end
}


now the macro will allow direct variable params, so in your code:

Code:
print('Buffer contents BEFORE memFill:  "', buf1, '"\r\n');

memFill(@buf1, 0, ord('y'));
print('Buffer contents AFTER memFill 0: "', buf1, '"\r\n');


Everything should work.

Download Ziron
Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.
Admin
Site Admin

avatar

(send private message)

Posts: 933
Topics: 55

Location:
OverHertz Studio
[1461] - posted: 2015-01-14 18:50:38
OK, I have made a small adjustment to your function and will add it to the RTL memutils.zir as per your request.

Code:
/*
/    Fill block of memory with specified value
/    $buf -- Pointer to block of memory to fill
/    $len -- Value to be set
/    $ch_ -- Number of bytes to set to value
/    Copyright (c) 0CodErr, KolibriOS team
*/
inline function m_memFill($buf, $len, $_ch) {
  push edi

  eax = 0;
  al = $_ch;
  edx = $len;
  edi = $buf;
  push edi
  ecx = eax;
  ah = al;
  ch = cl;
  ecx << 16;
  or eax, ecx;
  ecx = edx;
  ecx >> 2;
  and edx, 3;
  rep stosd;
  ecx = edx;
  rep stosb;

  pop eax
  pop edi
  
  $return eax;
}

function memFill(char* buf; dword len; char ch_) {
  eax = m_memFill(buf, len, ch_);
}


Download Ziron
Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.
0CodErr
Ziron Guru
(send private message)

Posts: 199
Topics: 37

Location:
[1462] - posted: 2015-01-15 10:14:38
Actually in the description must be Code:
/    $len -- Number of bytes to set to value
/    $ch_ -- Value to be set
Need to change places of lines.
Admin
Site Admin

avatar

(send private message)

Posts: 933
Topics: 55

Location:
OverHertz Studio
[1466] - posted: 2015-01-15 11:02:21
Fixed smile

Download Ziron
Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.
0CodErr
Ziron Guru
(send private message)

Posts: 199
Topics: 37

Location:
[1474] - posted: 2015-01-17 13:05:40
Just question. Why you replaced in memFill Code:
uses edi;
with Code:
push edi \ pop edi
?
Pages: 1 2
create new reply


Quick reply:

Message:



Currently Active Users:
There are currently 3 user(s) online. 0 member(s) and 3 guest(s)
Most users ever online was 1046, January 28, 2022, 2:08 pm.


Statistics:
Threads: 225 | Posts: 1848 | Members: 51 | Active Members: 51
Welcome to our newest member, yecate
const Copyright = '2011-2024 © OverHertz Ltd. All rights reserved.';
Web development by OverHertz Ltd