Jump to page: 1 2
Thread overview
VLA in Assembler
Dec 17, 2014
Foo
Dec 17, 2014
bearophile
Dec 17, 2014
Foo
Dec 17, 2014
uri
Dec 17, 2014
Foo
Dec 17, 2014
Adam D. Ruppe
Dec 17, 2014
btdc
Dec 17, 2014
btdc
Dec 17, 2014
Foo
Dec 17, 2014
btdc
Dec 17, 2014
Namespaces
Dec 17, 2014
Adam D. Ruppe
Dec 17, 2014
Foo
December 17, 2014
Hi,
Could someone explain me, if and how it is possible to allocate a variable length array with inline assembly?
Somewhat like
----
int[] arr;
int n = 42;
asm {
    // allocate n stack space for arr
}
----
I know it is dangerous and all that, but I just want it know. ;)
December 17, 2014
Foo:

> Hi,
> Could someone explain me, if and how it is possible to allocate a variable length array with inline assembly?
> Somewhat like
> ----
> int[] arr;
> int n = 42;
> asm {
>     // allocate n stack space for arr
> }
> ----
> I know it is dangerous and all that, but I just want it know. ;)

Doing it with alloca is simpler:


void main() @nogc {
    import core.stdc.stdlib: alloca, exit;

    alias T = int;
    enum n = 42;

    auto ptr = cast(T*)alloca(T.sizeof * n);
    if (ptr == null)
        exit(1); // Or throw a memory error.
    auto arr = ptr[0 .. n];
}


Bye,
bearophile
December 17, 2014
On Wednesday, 17 December 2014 at 10:59:09 UTC, bearophile wrote:
> Foo:
>
>> Hi,
>> Could someone explain me, if and how it is possible to allocate a variable length array with inline assembly?
>> Somewhat like
>> ----
>> int[] arr;
>> int n = 42;
>> asm {
>>    // allocate n stack space for arr
>> }
>> ----
>> I know it is dangerous and all that, but I just want it know. ;)
>
> Doing it with alloca is simpler:
>
>
> void main() @nogc {
>     import core.stdc.stdlib: alloca, exit;
>
>     alias T = int;
>     enum n = 42;
>
>     auto ptr = cast(T*)alloca(T.sizeof * n);
>     if (ptr == null)
>         exit(1); // Or throw a memory error.
>     auto arr = ptr[0 .. n];
> }
>
>
> Bye,
> bearophile
Yes I know, but I really want it in inline assembly. It's for learning purpose. :)
December 17, 2014
On Wednesday, 17 December 2014 at 11:39:43 UTC, Foo wrote:
> On Wednesday, 17 December 2014 at 10:59:09 UTC, bearophile wrote:
>> Foo:
>>
>>> Hi,
>>> Could someone explain me, if and how it is possible to allocate a variable length array with inline assembly?
>>> Somewhat like
>>> ----
>>> int[] arr;
>>> int n = 42;
>>> asm {
>>>   // allocate n stack space for arr
>>> }
>>> ----
>>> I know it is dangerous and all that, but I just want it know. ;)
>>
>> Doing it with alloca is simpler:
>>
>>
>> void main() @nogc {
>>    import core.stdc.stdlib: alloca, exit;
>>
>>    alias T = int;
>>    enum n = 42;
>>
>>    auto ptr = cast(T*)alloca(T.sizeof * n);
>>    if (ptr == null)
>>        exit(1); // Or throw a memory error.
>>    auto arr = ptr[0 .. n];
>> }
>>
>>
>> Bye,
>> bearophile
> Yes I know, but I really want it in inline assembly. It's for learning purpose. :)

You could look at the disassembly.
December 17, 2014
On Wednesday, 17 December 2014 at 12:15:23 UTC, uri wrote:
> On Wednesday, 17 December 2014 at 11:39:43 UTC, Foo wrote:
>> On Wednesday, 17 December 2014 at 10:59:09 UTC, bearophile wrote:
>>> Foo:
>>>
>>>> Hi,
>>>> Could someone explain me, if and how it is possible to allocate a variable length array with inline assembly?
>>>> Somewhat like
>>>> ----
>>>> int[] arr;
>>>> int n = 42;
>>>> asm {
>>>>  // allocate n stack space for arr
>>>> }
>>>> ----
>>>> I know it is dangerous and all that, but I just want it know. ;)
>>>
>>> Doing it with alloca is simpler:
>>>
>>>
>>> void main() @nogc {
>>>   import core.stdc.stdlib: alloca, exit;
>>>
>>>   alias T = int;
>>>   enum n = 42;
>>>
>>>   auto ptr = cast(T*)alloca(T.sizeof * n);
>>>   if (ptr == null)
>>>       exit(1); // Or throw a memory error.
>>>   auto arr = ptr[0 .. n];
>>> }
>>>
>>>
>>> Bye,
>>> bearophile
>> Yes I know, but I really want it in inline assembly. It's for learning purpose. :)
>
> You could look at the disassembly.

And how? I'm on Windows.
December 17, 2014
On Wednesday, 17 December 2014 at 10:35:39 UTC, Foo wrote:
> Hi,
> Could someone explain me, if and how it is possible to allocate a variable length array with inline assembly?
> Somewhat like
> ----
> int[] arr;
> int n = 42;
> asm {
>     // allocate n stack space for arr
> }
> ----
> I know it is dangerous and all that, but I just want it know. ;)

It's probably something like that:

module runnable;

import std.stdio;
import std.c.stdlib;

ubyte[] newArr(size_t aLength)
{
    asm
    {
        naked;

        mov ECX, EAX;       // saves aLength in ECX

        push ECX;
        call malloc;        // .ptr =  malloc(aLength);
        mov ECX,[EAX];      // saved the .ptr of our array

        mov EAX, 8;         // an array is a struct with length and ptr
                            // so 8 bytes in 32 bit
        call malloc;        // EAX points to the first byte of the struct

        mov [EAX + 4], ECX; // .ptr
        pop ECX;
        mov [EAX], ECX;     // .length
        mov EAX, [EAX];     // curretnly EAX is a ref, so need to dig...

        ret;
    }
}

try and see ;) Actually it may be wrong

December 17, 2014
On Wednesday, 17 December 2014 at 12:54:44 UTC, btdc wrote:
> On Wednesday, 17 December 2014 at 10:35:39 UTC, Foo wrote:
>> Hi,
>> Could someone explain me, if and how it is possible to allocate a variable length array with inline assembly?
>> Somewhat like
>> ----
>> int[] arr;
>> int n = 42;
>> asm {
>>    // allocate n stack space for arr
>> }
>> ----
>> I know it is dangerous and all that, but I just want it know. ;)
>
> It's probably something like that:
>
> module runnable;
>
> import std.stdio;
> import std.c.stdlib;
>
> ubyte[] newArr(size_t aLength)
> {
>     asm
>     {
>         naked;
>
>         mov ECX, EAX;       // saves aLength in ECX
>
>         push ECX;
>         call malloc;        // .ptr =  malloc(aLength);
>         mov ECX,[EAX];      // saved the .ptr of our array
>
>         mov EAX, 8;         // an array is a struct with length and ptr
>                             // so 8 bytes in 32 bit
>         call malloc;        // EAX points to the first byte of the struct
>
>         mov [EAX + 4], ECX; // .ptr
>         pop ECX;
>         mov [EAX], ECX;     // .length
>         mov EAX, [EAX];     // curretnly EAX is a ref, so need to dig...
>
>         ret;
>     }
> }
>
> try and see ;) Actually it may be wrong

fuck...the comments are once again cut...
December 17, 2014
And it is using malloc... ;)
I wanted something that increases the stack pointer ESP.

e.g.
----
void main()
{
	int[] arr;
	int n = 42;
	
	writeln(arr.length);
	writeln(arr.ptr);
	
	asm {
		mov EAX, n;
		mov [arr + 8], ESP;
		sub [ESP], EAX;
		mov [arr + 0], EAX;
	}
	
	writeln(arr.length);
	//writeln(arr[0]);
}
----
but that does not work...
December 17, 2014
On Wednesday, 17 December 2014 at 12:29:53 UTC, Foo wrote:
> And how? I'm on Windows.

Digital Mars sells an obj2asm function that will disassemble dmd generated code. I think it is in the $15 basic utility package.

But VLA/alloca is more complex than a regular function - the compiler needs to know about it to adjust for the changed stack. It'll take more length to write this up, I'll do it in a separate post.
December 17, 2014
On Wednesday, 17 December 2014 at 14:11:32 UTC, Foo wrote:
> And it is using malloc... ;)
> I wanted something that increases the stack pointer ESP.
>
> e.g.
> ----
> void main()
> {
> 	int[] arr;
> 	int n = 42;
> 	
> 	writeln(arr.length);
> 	writeln(arr.ptr);
> 	
> 	asm {
> 		mov EAX, n;
> 		mov [arr + 8], ESP;
> 		sub [ESP], EAX;
> 		mov [arr + 0], EAX;
> 	}
> 	
> 	writeln(arr.length);
> 	//writeln(arr[0]);
> }
> ----
> but that does not work...

You cant always get what you want. try more, speak less.

« First   ‹ Prev
1 2