Advertisement

Problem using inline assembler

Started by April 24, 2001 06:13 PM
2 comments, last by CPlasmaGuns 23 years, 9 months ago
I haven''t used assembler in a long time, and I don''t know very many instructions with it, but I''m trying to replace pieces of game in C++ with inline assembler code to see if I can''t get a little speed increase, and also to learn more assembler. Anyway, the section of C++ code I''m replacing is just a memcpy call, but when I rewrite it in assembler and execute, my game crashes (terminates): memcpy( (void *)(lpSurface+start_x+run_i->first), (const void *)run_i->second.begin(), run_i->second.size() ); // this code works fine and does not crash lpSurface is a BYTE * to locked 256-color surface run_i is a pointer to a pair >, so it represents a run of pixels (the vector part is a bunch of pixels) with an x-coordinate (the DWORD is its x-coordinate). Of course, I used the standard vector<> and pair<> classes that are part of the C++ template library, not my own version. start_x is the overall x-offset. This is the assembler code: __asm { ; clear direction flag to copy forward cld ; Point es:di at lpSurface+start_x+run_i->first mov eax,lpSurface add eax,start_x add eax,[run_i].first mov ebx,eax mov eax,lpSurface mov lpSurface,ebx les di,lpSurface mov lpSurface,eax ; Point ds:si at source lds si,[run_i].second._First ; set byte count mov ecx,[run_i].second._Last sub ecx,[run_i].second._First ; move the data rep movsb } // this code crashes and burns. Any idea why? I looked at the implementation of the vector class, and _First is a pointer to the first element in the array, and _Last is a pointer that points just beyond the end of it (so _Last - _First should be the size) Thanks in advance.
ahhh your code is bad man
btw-if you want your game to run on INTEL pentiums
so change
rep movsb
to

bla:
mov eax, [esi]
mov [edi], eax
dec cx
jnz bla

which is faster on pentiums!

ok now doing a memcpy asm in vc will NOT help you !
believe me, VC''s memcpy code is FAR FASTER than yours
so you should stick to VC''s memcpy
which is 32 bits, and yours is 8(SLOW!!) bits per loop

so if you want to make your game faster this is not the RIGHT
function to translate into asm

but if you insist to translate this code to asm
i''m willing to help!

Arkon
http://qsoft.cjb.net
Advertisement
Seeing that the quality of your asm code isn''t much better than mine (I''m currently learning asm in my own sweet time), I suggest you learn by reading the book Art of Assembly Language Programming and look at the listing files generated by MSVC (project->Settings->C/C++->Listing Files ->Assembly with Soirce). That''s the way I''m learning at the moment, and it is going well.

And that memcpy you wrote was complex and slow
==========================================In a team, you either lead, follow or GET OUT OF THE WAY.
> btw-if you want your game to run on INTEL pentiums
> so change
> rep movsb
> to
>
> bla:
> mov eax, [esi]
> mov [edi], eax

better say "if you want to run your game at all..."
ds:si es:di are dead. 32 bits eradicated them, left are only esi and edi.

memcpy( (void *)(lpSurface+start_x+run_i->first),
(const void *)run_i->second.begin(),
run_i->second.size()
);

  // First, I''d use C++ to get the values.// The compiler may have cached some referencesvoid *sourceptr = lpSurface + start_x + run_i->first;void *destptr = run_i->second.begin();int   size = second.size();// If you just want to copyasm {  mov edi, sourceptr                // Get src ptr  mov esi, destptr                  // Get dst ptr  mov ecx, size                     // Get size  mov edx, ecx                       shr ecx, 2                        // Get # of DWORDs (4 byte)  and edx, 3                        // Get remaining bytes  rep movsd                         // Copy ecx DWORDs  mov ecx, edx   rep movsb                         // Copy ecx BYTEs (rest)}// If you''d like to modify the valuesasm {  mov edi, sourceptr                // Get src ptr  mov esi, destptr                  // Get dst ptr  mov ecx, size                     // Get size_mcpy:  mov eax, [esi]                    // Load value  add esi, 4  or  eax, 0xF0000000               // modify somehow ;)  mov [edi], eax                    // Store value  add edi,4  dec ecx  jnz _mcpy                         // Loop ecx times}  


That''s it.
Sorry, wrote it in the browser, but I''m sure it''s correct

-Markus-
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.

This topic is closed to new replies.

Advertisement