assembler copy char[]

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Thu Jun 7 03:56:14 PDT 2007


nobody wrote:
> i try copy mystring to st in assembler. 
> Can someone give me an advice how to do this.
> 
> import std.stdio;
> void main()
> {
>         char[] mystring = "Hey Assembler\n";
>         char[] st;
> 
>         asm
>         {
>                 mov EAX, dword ptr [mystring+4];
>                 mov st,EAX;
>         }
>         writefln("st: ", st);
> }
> 
> I get a Segmentation fault .

Unsurprising, since you're copying mystring.ptr to st.length, creating 
an array reference to a (likely huge) array with (.ptr == null) ;).

Like Daniel, who posted while I was composing this post, I wonder why 
you're trying to do this. There's a much easier way that can likely be 
better optimized by the compiler.
But if you're determined to do this (or are just trying to expand your 
knowledge of asm coding and/or D array implementation), read on.

Assuming you're trying to code "st = mystring" in assembler, try this:
---
import std.stdio;
void main()
{
         char[] mystring = "Hey Assembler\n";
         char[] st;

         asm
         {
		// Copy length
                 mov EAX, dword ptr [mystring];
                 mov [st],EAX;
		
		// Copy ptr
                 mov EAX, dword ptr [mystring+4];
                 mov [st+4],EAX;
         }
         writefln("st: ", st);
}
---
Remember, dynamic arrays have two parts: a length and a pointer to the 
data. You need to copy both of them (and to the corresponding part of 
the destination, obviously) to copy a dynamic array reference.



P.S. It'll likely be a bit more efficient to do this:
---
         asm
         {
                 mov ECX, dword ptr [mystring];
                 mov EDX, dword ptr [mystring+4];
                 mov [st],ECX;
                 mov [st+4],EDX;
		
         }
---
because it leaves more time between reading and writing, allowing the 
CPU to perform better pipelining.
About register usage: I used ECX & EDX here because (like EAX) those 
don't need to be preserved between function calls, so the compiler 
doesn't necessarily need to insert extra code to preserve them. I didn't 
use EAX because that's more likely to contain a useful value due to its 
special uses in calling conventions, and is thus more likely to require 
extra code to be emitted to preserve it.

But better optimization would likely result from just changing it to "st 
= mystring" and adding '-O' (or '-O3' for GDC) to the command line 
options passed to the compiler :). (Plus it'll be platform-independent)


More information about the Digitalmars-d-learn mailing list