fritz os typo?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
tbone

fritz os typo?

Post by tbone »

I was looking through fritz os source and I saw this function memset in kernelasm:
memset:
   push ebp
   mov ebp, esp
   mov edi, [ebp + 8]   ???   
   mov edi, [ebp +12]   ???   
   mov eax, [ebp + 16]      
   push edi         
   cld            rep stosb
   pop eax            pop ebp            ret
I'm not a big asm guru especially in this kind of programming but is this true?
jrfritz

Re:fritz os typo?

Post by jrfritz »

It is not a typo. The function is in Assembler, since I don't know where some C code for that is.

The C++ kernel calles that function.
jrfritz

Re:fritz os typo?

Post by jrfritz »

Also...I have a FritzOS forum here:

http://fritzos.sourceforge.net/yabbse
tbone

Re:fritz os typo?

Post by tbone »

I think i have some c code for that:
Algorithm:

char * memset (dst, value, count)
char *dst;
char value;
unsigned int count;
{
char *start = dst;

while (count--)
*dst++ = value;
return(start);
} ;)
jrfritz

Re:fritz os typo?

Post by jrfritz »

Thankyou...i'll try that later...i'm retyping up my header files...changing alot of stuff.
Slasher

Re:fritz os typo?

Post by Slasher »

the asm code is fine, just some errors.
rep stosb uses (E)CX for the number of bytes to store and not (E)AX.
The POP EAX at the end returns DESTINATION ADRESS.
push ebp
mov ebp, esp
mov edi, [ebp + 8] ???
mov edi, [ebp +12] ???
mov eax, [ebp + 16]
push edi
cld rep stosb
pop eax pop ebp ret
this should be
push ebp
mov ebp, esp
mov esi,[ebp + 8] ;source address
mov edi,[ebp +12] ;destination address
mov ecx,[ebp + 16] ;number of bytes to store
push edi ;push destination address onto the stack
cld ;increment edi and esi automatically
rep stosb
pop eax ;pop destination adress from stack into eax
mov esp,ebp
pop ebp
ret
jrfritz

Re:fritz os typo?

Post by jrfritz »

Pype.Clicker told me it would take less CPU cycles if it was in C.
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:fritz os typo?

Post by df »

if you really want an ASM memmove that works properly (calcs source+dest correctly, size, etc)

Code: Select all

/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
   .file "memmove.s"
   .align 4
   .globl   _memmove
_memmove:
   pushl   %ebp
   movl   %esp,%ebp
   pushl   %esi
   pushl   %edi
   movl   8(%ebp),%edi
   movl   12(%ebp),%esi
   movl   16(%ebp),%ecx
   jecxz   L2
   cld
   cmpl   %esi,%edi
   jb   L3

   std
   addl   %ecx,%esi
   addl   %ecx,%edi
   decl   %esi
   decl   %edi
L3:
   rep
   movsb

L2:
   cld
   popl   %edi
   popl   %esi
   movl   8(%ebp),%eax
   leave
   ret
-- Stu --
jrfritz

Re:fritz os typo?

Post by jrfritz »

Ok...could you show me the C def for that so I can use the extern "C"?
Slasher

Re:fritz os typo?

Post by Slasher »

hi,
That only holds for POORLY WRITTEN ASSEMBLY CODE!!!
If you know what you are doing in a short asm routine, then is very difficult for the C compiler to generate code that takes LESS CPU CYCLES TO DO THE SAMETHING!
Why do you think they say a way to OPTIMIZE CODE IS TO REWRITE IMPORTANT PARTS IN ASSEMBLY!!!
jrfritz

Re:fritz os typo?

Post by jrfritz »

I'm not a asm person...

anyway...

what's the C def for the function, df?
Schol-R-LEA

Re:fritz os typo?

Post by Schol-R-LEA »

Code Slasher wrote: hi,
That only holds for POORLY WRITTEN ASSEMBLY CODE!!!
If you know what you are doing in a short asm routine, then is very difficult for the C compiler to generate code that takes LESS CPU CYCLES TO DO THE SAMETHING!
Why do you think they say a way to OPTIMIZE CODE IS TO REWRITE IMPORTANT PARTS IN ASSEMBLY!!!
True enough, but poorly optimized assembly code is a lot easier to write than poorly optimized C code :). While it is true that it is always possible for a skilled and knowledgable assembly programmer to write a given code section more efficiently than any compiler, it is also true that:
  • such skills are rare, especially today.
  • even the best assembly coder cannot always write optimal code, while a compiler can optimize whole programs to some degree,
  • compilers can (in principle) apply different techniques that no human programmer would be able to use practically,
  • doing a mediocre job of optimizing a whole program is less useful that effectively optimizing critical sections of the program, and
  • there is no way to tell ahead of time where such critical sections are - only by profiling the code and measuring it's performance can you know what needs to be optimized.
It may not take few clock cycles to run the C version, but it may well take fewer clock cycles to write and run the C version than it would to carefully optimize the assembly version.

That having been said, it is true that an efficient assembly version of this particular function is trivial. My onw version is quite similar to the deLorie version, although thinking of it, I have not actually tested mine out... I'll have to get to that, soon.
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:fritz os typo?

Post by df »

Tom wrote: I'm not a asm person...

anyway...

what's the C def for the function, df?
uh, its ansi-c, the memmove definition never changes. it should be the same in any os.


AAAARGH! just realised i pasted memmove, but we are talking about memset! doh.... eesh i'm a bit off today. (finishing off my keyboard driver).

anyway, here is the memset as I should have pasted before.

definitions

Code: Select all

void*   memmove(void *__dest, const void *__src, size_t __n);
void*   memset(void *__s, int __c, size_t __n);

Code: Select all

/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
   .file "memset.s"
   .text
   .align   4
   .globl   _memset

_memset:
   pushl   %ebp
   movl   %esp,%ebp
   pushl   %edi
   movl   8(%ebp),%edi
   movl   12(%ebp),%eax
   movl   16(%ebp),%ecx
   cld

   # We will handle memsets of <= 15 bytes one byte at a time.
   # This avoids some extra overhead for small memsets, and
   # knowing we are setting > 15 bytes eliminates some annoying
   # checks in the "long move" case.
   cmpl   $15,%ecx
   jle   L3

   # Otherwise, tile the byte value out into %eax.
   # 0x41 -> 0x41414141, etc.
   movb   %al,%ah
   movl   %eax,%edx
   sall   $16,%eax
   movw   %dx,%ax
   jmp   L2

   # Handle any cruft necessary to get %edi long-aligned.
L1:   stosb
   decl   %ecx
L2:   testl   $3,%edi
   jnz   L1

   # Now slam out all of the longs.
   movl   %ecx,%edx
   shrl   $2,%ecx
   rep
   stosl

   # Finally, handle any trailing cruft.  We know the high three bytes
   # of %ecx must be zero, so just put the "slop count" in the low byte.
   movb   %dl,%cl
   andb   $3,%cl
L3:   rep
   stosb
   popl   %edi
   movl   8(%ebp),%eax
   leave
   ret
-- Stu --
Schol-R-LEA

Re:fritz os typo?

Post by Schol-R-LEA »

This is probably a better version, as it correctly saves the registers that have to be preserved, and checks for the zero-length case.

memset:
push ebp
mov ebp, esp
mov ecx, [ebp + 16] ; 3rd arg - string size in bytes
jecxz .sizezero
push edi ; save value to restore later
mov edi, [ebp + 8] ; first arg - buffer pointer
mov eax, [ebp +12] ; 2nd arg - value to write
push edi ; return value - save now, before EDI gets trashed
cdl ; make sure direction flag set correctly
rep stosb
pop eax ; recover return value
pop edi
.sizezero:
pop ebp ; restore caller's stack frame
ret 3

Again, this hasn't actually been tested yet.
Slasher

Re:fritz os typo?

Post by Slasher »

hi,
I didn't say WRITE FULL PROGRAMS IN ASM! Said ROUTINES! Also any ROUTINE that is called A LOT or is used in LOOPS is a candidate for ASM optimization. Also you need to know what you are doing to get it right, just as i stated before!
Post Reply