flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Memory copying macro

Author
Thread Post new topic Reply to topic
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 09 Nov 2004, 17:00
What do you think about this memory_copy macro I made?
It always chooses the shortest form to copy. It uses esi and edi as pointers, but it's no problem to make this macro preserve them....

So what do you think?

Code:
macro  memcpy src, dest, size {
       ..copy  = 0

       if      src  eq          esi
       else
              mov  esi,src
       end     if

       if      dest eq     edi
       else
              mov  edi,dest
       end     if

       if      size eqtype 0
              ..copy  = 1
         if      (size mod 4) = 0
                    mov  ecx,(size shr 2)
                       rep  movsd
          else
                mov  ecx,(size shr 2)
                       rep  movsd
                  mov  ecx,(size mod 4)
                       rep  movsb
          end     if
       end     if

       if      ..copy  =    0
        if      size    eq     ecx
          else
                mov  ecx,size
               end     if

              push    ecx
         shr     ecx,2
               rep     movsd
               pop     ecx
         and     ecx,3
               rep     movsb
       end     if
}

memcpy esi,edi,ecx
memcpy [pointer1],[pointer2],[size]
memcpy eax,[hMappedFile],edx
    


I also have some idea, look:
Code:
                    mov  ecx,(size mod 4)
                       rep  movsb
    

if it's (mod 4) so it is in range: 1,2,3 (0 can't be, because if so, the macro stops earlier). So maybe, instead of this what I used, better will be to use movsb with repeat directive (or even add another compare, and give movsw for special circumstances Smile). Will it be better?
Post 09 Nov 2004, 17:00
View user's profile Send private message Visit poster's website Reply with quote
Vortex



Joined: 17 Jun 2003
Posts: 318
Vortex 09 Nov 2004, 17:20
Hutch's masm32.lib provides a function for this purpose, it should not be so hard to translate it to Fasm:
Code:
align 4

MemCopy proc public uses esi edi Source:PTR BYTE,Dest:PTR BYTE,ln:DWORD

    ; ---------------------------------------------------------
    ; Copy ln bytes of memory from Source buffer to Dest buffer
    ;      ~~                      ~~~~~~           ~~~~
    ; USAGE:
    ; invoke MemCopy,ADDR Source,ADDR Dest,4096
    ;
    ; NOTE: Dest buffer must be at least as large as the source
    ;       buffer otherwise a page fault will be generated.
    ; ---------------------------------------------------------

    cld
    mov esi, [Source]
    mov edi, [Dest]
    mov ecx, [ln]

    shr ecx, 2
    rep movsd

    mov ecx, [ln]
    and ecx, 3
    rep movsb

    ret

MemCopy endp
    

_________________
Code it... That's all...
Post 09 Nov 2004, 17:20
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 09 Nov 2004, 18:00
It would also be good to ensure the proper alignment (some MOVSB's both on the beginning and at the end might be needed). Though it might not be possible to make the source and destination address be both aligned on dword for MOVSD, for example.
Post 09 Nov 2004, 18:00
View user's profile Send private message Visit poster's website Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1166
Location: Overflow
Matrix 09 Nov 2004, 18:20
what do you think on my memcopy macro? :DDD
It always chooses the shortest form to copy Very Happy

well i put it in main because its not really a macro, its more a procedure/algorithm
http://board.flatassembler.net/topic.php?p=17998#17998
Post 09 Nov 2004, 18:20
View user's profile Send private message Visit poster's website Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 10 Nov 2004, 13:26
I guess you didn't look precisely at my macro. Look at your code Vortex:

Vortex wrote:

Code:
    [...]
    shr ecx, 2
    rep movsd

    mov ecx, [ln]
    and ecx, 3
    rep movsb
    [...]
    



If my macro is given a constant value it checks this constant number for being a multiple of 4. If so the last 3 lines of your code are useless (data can be copied using only movsd) and my macro doesn't put them in code. If the value given is not a multiple of 4 or it is given as a register or variable then it does the same as the code you've pasted. But for special circumstances it is smaller.

Matrix: I can't move it to main, because, a procedure gets parameters from stack and my macro makes some operations on the number of bytes to copy if it's a constant value. Such operations are impossible if given on a stack.

Privalov: It does align it. Look: it counts how many dwords are there and moves them with movsd, and then it counts how many bytes are left to align it by counting size mod 4 and movsb it.
Post 10 Nov 2004, 13:26
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8376
Location: Kraków, Poland
Tomasz Grysztar 10 Nov 2004, 16:49
But the address of each double word may not be aligned on 4 boundary. For example when you start moving from address 10001h, it might be good to use one MOVSB first, then as much of (aligned) MOVSD instructions as fit, and then fill the rest with MOVSB instructions again.
Post 10 Nov 2004, 16:49
View user's profile Send private message Visit poster's website Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1166
Location: Overflow
Matrix 10 Nov 2004, 17:36
Reverend wrote:
I guess you didn't look precisely at my macro. Look at your code Vortex:

Matrix: I can't move it to main, because, a procedure gets parameters from stack and my macro makes some operations on the number of bytes to copy if it's a constant value. Such operations are impossible if given on a stack.


sorry i was not thinking of moving your thread, i just put my code there and linked it here, maeby it helps Smile

(my code was not a macro so i post it there)
Post 10 Nov 2004, 17:36
View user's profile Send private message Visit poster's website Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 11 Nov 2004, 10:06
Privalov wrote:
But the address of each double word may not be aligned on 4 boundary. For example when you start moving from address 10001h, it might be good to use one MOVSB first, then as much of (aligned) MOVSD instructions as fit, and then fill the rest with MOVSB instructions again.

Ok, now I know what you meant. It's a nice idea, but addresses are in 99% not a constant value so no preprocessing can be done. Of course it might be done during runtime using another instructions, but to tell you the truth I didn't wrote these to be extra-fast, just a small example to put it somewhere in the code
Post 11 Nov 2004, 10:06
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.