Inline assembler is supported with the asm statement:
AsmStatement:
asm { }
asm { AsmInstructionList }
AsmInstructionList:
AsmInstruction ;
AsmInstruction ; AsmInstructionList
An asm statement enables the direct use of assembly language instructions. This makes it easy to obtain direct access to special CPU features without resorting to an external assembler. The D compiler will take care of the function calling conventions, stack setup, etc.
The format of the instructions is, of course, highly dependent on the native instruction set of the target CPU, and so is implementation defined. But, the format will follow the following conventions:
-
It must use the same tokens as the D language uses.
-
The comment form must match the D language comments.
-
Asm instructions are terminated by a ;, not by an end of line.
These rules exist to ensure that D source code can be tokenized independently of syntactic or semantic analysis.
For example, for the Intel Pentium:
int x = 3;
asm
{
mov EAX,x; // load x and put it in register EAX
}
Inline assembler can be used to access hardware directly:
int gethardware()
{
asm
{
mov EAX, dword ptr 0x1234;
}
}
For some D implementations, such as a translator from D to C, an inline assembler makes no sense, and need not be implemented. The version statement can be used to account for this:
version (InlineAsm)
{
asm
{
...
}
}
else
{
... some workaround ...
}
Arrays
There are four kinds of arrays:
int* p;
|
Pointers to data
|
int[3] s;
|
Static arrays
|
int[] a;
|
Dynamic arrays
|
int[char[]] x;
|
Associative arrays (discussed later)
| Pointers
int* p;
These are simple pointers to data, analogous to C pointers. Pointers are provided for interfacing with C and for specialized systems work. There is no length associated with it, and so there is no way for the compiler or runtime to do bounds checking, etc., on it. Most conventional uses for pointers can be replaced with dynamic arrays, out and inout parameters, and handles (references).
Static Arrays
int[3] s;
These are analogous to C arrays. Static arrays are distinguished by having a length fixed at compile time.
Dynamic Arrays
int[] a;
Dynamic arrays contain a length and a garbage collected pointer to the array data.
Array Declarations
There are two ways to declare arrays, prefix and postfix. The prefix form is the preferred method, especially for non-trivial types.
Prefix Array Declarations
Prefix declarations appear before the identifier being declared and read right to left, so:
int[] a; // dynamic array of ints
int[4][3] b; // array of 3 arrays of 4 ints each
int[][5] c; // array of 5 dynamic arrays of ints.
int*[]*[3] d; // array of 3 pointers to dynamic arrays of pointers to ints
int[]* e; // pointer to dynamic array of ints
Postfix Array Declarations
Postfix declarations appear after the identifier being declared and read left to right. Each group lists equivalent declarations:
// dynamic array of ints
int[] a;
int a[];
// array of 3 arrays of 4 ints each
int[4][3] b;
int[4] b[3];
int b[3][4];
// array of 5 dynamic arrays of ints.
int[][5] c;
int[] c[5];
int c[5][];
// array of 3 pointers to dynamic arrays of pointers to ints
int*[]*[3] d;
int*[]* d[3];
int* (*d[3])[];
// pointer to dynamic array of ints
int[]* e;
int (*e[]);
Rationale: The postfix form matches the way arrays are declared in C and C++, and supporting this form provides an easy migration path for programmers used to it.
Usage
There are two broad kinds of operations to do on an array - affecting the handle to the array, and affecting the contents of the array. C only has operators to affect the handle. In D, both are accessible.
The handle to an array is specified by naming the array, as in p, s or a:
int* p;
int[3] s;
int[] a;
int* q;
int[3] t;
int[] b;
p = q; p points to the same thing q does.
p = s; p points to the first element of the array s.
p = a; p points to the first element of the array a.
s = ...; error, since s is a compiled in static
reference to an array.
a = p; error, since the length of the array pointed
to by p is unknown
a = s; a is initialized to point to the s array
a = b; a points to the same array as b does
Slicing
Slicing an array means to specify a subarray of it. For example:
int[10] a; declare array of 10 ints
int[] b;
b = a[1..3]; a[1..3] is a 2 element array consisting of
a[1] and a[2]
The [] is shorthand for a slice of the entire array. For example, the assignments to b:
int[10] a;
int[] b;
b = a;
b = a[];
b = a[0 .. a.length];
are all semantically equivalent.
Slicing is not only handy for referring to parts of other arrays, but for converting pointers into bounds-checked arrays:
int* p;
int[] b = p[0..8];
Share with your friends: |