assembler copy char[]

Don Clugston dac at nospam.com.au
Thu Jun 7 05:34:51 PDT 2007


nobody wrote:
> Frits van Bommel Wrote:
> 
>> 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.
> 
> Yes i try to learn Inline Assembler but it is more
> difficult then i thought ;-)
> 
>> 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.
> 
> Yes i figured this out.
> 
>  You need to copy both of them (and to the corresponding part of 
>> the destination, obviously) to copy a dynamic array reference.
> 
> Ah, that's the trick.
>>
>>
>> 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)
> 
> Wow, that's exactly what i want.
> In dmd it's all ok, but the gdc  didn't like it: 
> 
> mov EDX, dword ptr [mystring+4];
> mov [st+4],EDX;
> 
> 
> gdmd  string.d
> /tmp/cc4h5AKo.s: Assembler messages:
> /tmp/cc4h5AKo.s:30: Error: junk `(%ebp)+4' after expression
> /tmp/cc4h5AKo.s:31: Error: junk `(%ebp)+4' after expression
> 
> 
> 
ST is a register (top of stack in x87 FPU). In DMD, all registers must be 
uppercase; maybe not true for GDC.


More information about the Digitalmars-d-learn mailing list