www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How can I point an array to existing data in memory while using Better

reply Stijn Herreman <stijn.herreman outlook.be> writes:
https://forum.dlang.org/thread/ddckhvcxlyuvuiyazpqy forum.dlang.org is similar
to what I want to do, but the code by Adam cannot be used when using Better C
(I assume slicing isn't supported).

I have the following code:

environment.d

     public __gshared header* GPT_header;
     public __gshared partition_entry[128] GPT_entries;

main.d

     GPT_header = cast(header*)0x00007e00;
     *(GPT_entries).ptr = *(cast(partition_entry*)0x00008000);

Disassembled, the code from main.d looks like this:

mov     ds:_D4boot11environment10GPT_headerPSQBg3gpt6header, 7E00h
mov     esi, 8000h
mov     edi, offset 
_D4boot11environment11GPT_entriesG128SQBk3gpt15partition_entry
mov     ecx, 20h
rep movsd

So GPT_header points to 0x7e00 as desired, but for GPT_entries it 
copies the first array element to a different location and makes 
it point to that location instead of 0x8000.

I should point out that I only have a vague idea of what I'm 
doing, I tried things until it compiled and worked (at first 
glance). If there are any docs that properly explain the casting 
of pointers, I'd appreciate the links.
Jul 08 2018
next sibling parent reply ag0aep6g <anonymous example.com> writes:
On 07/08/2018 10:27 PM, Stijn Herreman wrote:
 https://forum.dlang.org/thread/ddckhvcxlyuvuiyazpqy forum.dlang.org is 
 similar to what I want to do, but the code by Adam cannot be used when 
 using Better C (I assume slicing isn't supported).
Slicing a pointer works fine for me with -betterC (DMD 2.081.0). Why do you think it doesn't work?
 I have the following code:
 
 environment.d
 
      public __gshared header* GPT_header;
      public __gshared partition_entry[128] GPT_entries;
 
 main.d
 
      GPT_header = cast(header*)0x00007e00;
      *(GPT_entries).ptr = *(cast(partition_entry*)0x00008000);
 
 Disassembled, the code from main.d looks like this:
 
 mov     ds:_D4boot11environment10GPT_headerPSQBg3gpt6header, 7E00h
 mov     esi, 8000h
 mov     edi, offset 
 _D4boot11environment11GPT_entriesG128SQBk3gpt15partition_entry
 mov     ecx, 20h
 rep movsd
 
 So GPT_header points to 0x7e00 as desired, but for GPT_entries it copies 
 the first array element to a different location and makes it point to 
 that location instead of 0x8000.
As far as I can tell, the assembler code does exactly what your D code says: Copy one partition_entry (size is apparently 128 bytes?) from 0x8000 to GPT_entries[0]. If you want to set the .ptr of GPT_entries explicitly, I don't know if that's possible. But the code you have is not how you'd do it. You're dereferencing GPT_entries.ptr, you're not setting it. You can get a partition_entry[] that starts at 0x8000 by casting a pointer and slicing that. Works for me with -betterC: ---- struct partition_entry {} public __gshared partition_entry[] GPT_entries; extern(C) void main() { GPT_entries = (cast(partition_entry*) 0x8000)[0 .. 128]; } ----
Jul 08 2018
parent Stijn Herreman <stijn.herreman outlook.be> writes:
On Sunday, 8 July 2018 at 21:10:50 UTC, ag0aep6g wrote:
 On 07/08/2018 10:27 PM, Stijn Herreman wrote:
 https://forum.dlang.org/thread/ddckhvcxlyuvuiyazpqy forum.dlang.org is similar
to what I want to do, but the code by Adam cannot be used when using Better C
(I assume slicing isn't supported).
Slicing a pointer works fine for me with -betterC (DMD 2.081.0). Why do you think it doesn't work?
Oh it does, thank you for the example. I don't recall the code I had, but the compiler gave an error about TypeInfo (or a similar object) not being supported.
Jul 08 2018
prev sibling next sibling parent reply Stijn Herreman <stijn.herreman outlook.be> writes:
On Sunday, 8 July 2018 at 20:27:34 UTC, Stijn Herreman wrote:
 I should point out that I only have a vague idea of what I'm 
 doing, I tried things until it compiled and worked (at first 
 glance). If there are any docs that properly explain the 
 casting of pointers, I'd appreciate the links.
I found the following works as desired: environment.d public __gshared header* GPT_header; public __gshared partition_entry* GPT_entries; main.d GPT_header = cast(header*)0x00007e00; GPT_entries = cast(partition_entry*)0x00008000; That still lets me access GPT_entries with an index, e.g. GPT_entries[0]. Is this how it's supposed to be done, or is there a better way still?
Jul 08 2018
parent sarn <sarn theartofmachinery.com> writes:
On Sunday, 8 July 2018 at 21:11:53 UTC, Stijn Herreman wrote:
 On Sunday, 8 July 2018 at 20:27:34 UTC, Stijn Herreman wrote:
 I should point out that I only have a vague idea of what I'm 
 doing, I tried things until it compiled and worked (at first 
 glance). If there are any docs that properly explain the 
 casting of pointers, I'd appreciate the links.
I found the following works as desired: environment.d public __gshared header* GPT_header; public __gshared partition_entry* GPT_entries; main.d GPT_header = cast(header*)0x00007e00; GPT_entries = cast(partition_entry*)0x00008000; That still lets me access GPT_entries with an index, e.g. GPT_entries[0]. Is this how it's supposed to be done, or is there a better way still?
You can also easily make slices out of pointers. E.g.: // Some backing memory int[10] x; // Take a pointer int *xp = x.ptr; // Convert pointer to D slice int[] x2 = xp[0..10]; assert (x2.length == 10); (Of course, you don't need to break it into steps in real code, and it works fine in betterC.) There's still not a lot of info out there about doing betterC, but maybe you can find some examples in the following code. It works without any druntime at all, including TypeInfo. This is the entry point after a bootloader loads the D code and enters 32b protected mode: https://gitlab.com/sarneaud/xanthe/blob/master/src/os/drivers-bios.d#L198
Jul 08 2018
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 8 July 2018 at 20:27:34 UTC, Stijn Herreman wrote:
     public __gshared partition_entry[128] GPT_entries;
That's a block of memory rather than a pointer, so there's nothing to reassign there; the .ptr property is read-only there (and your reassignment is instead copying TO the address, instead of copying the address). Instead just use a partition_entry[] GPT_entries; and it is a reassignable pointer.
Jul 08 2018