Skip to content

Commit a672a4f

Browse files
committed
reworded, simplify, add some dfn
1 parent 67bd2f6 commit a672a4f

File tree

1 file changed

+51
-42
lines changed

1 file changed

+51
-42
lines changed

courses/fundamentals_of_ada/adv_280_low_level_programming.rst

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,10 @@ Record Representation Clauses
212212

213213
.. container:: column
214214

215-
* The developer can specify the exact mapping between a record and its binary representation
216-
* This mapping can be used for optimization purposes, or to match hardware requirements
215+
* Exact mapping between a record and its binary representation
216+
* Optimization purposes, or hardware requirements
217217

218-
- driver mapped on the address space, communication protocol, binary file representation...
218+
- Driver mapped on the address space, communication protocol...
219219

220220
* Fields represented as
221221

@@ -247,7 +247,7 @@ Record Representation Clauses
247247
Array Representation Clauses
248248
------------------------------
249249

250-
* The size of an array component can be specified with the `Component_Size` aspect (or attribute)
250+
* :ada:`Component_Size` for array's **components** size
251251

252252
.. code:: Ada
253253
@@ -258,42 +258,41 @@ Array Representation Clauses
258258
type Ar2 is array (1 .. 1000) of Boolean
259259
with Component_Size => 2;
260260
261-
------------------------------------------
262-
Endianness Specification (GNAT Specific)
263-
------------------------------------------
261+
--------------------------
262+
Endianness Specification
263+
--------------------------
264+
265+
* `Bit_Order` for a type's endianness
266+
* `Scalar_Storage_Order` for composite types
267+
268+
- Endianess of components' ordering
269+
- GNAT-specific
270+
- Must be consistent with `Bit_Order`
264271

265-
* GNAT allows defining the endianness through the `Scalar_Storage_Order` aspect, on composite types
266-
* Need to be associated with a consistent `Bit_Order` (convention for the bit range numbering)
267-
* The compiler will perform bitwise transformations if needed when sending data to the processor
272+
* Compiler will peform needed bitwise transformations when performing operations
268273

269274
.. code:: Ada
270275
271276
type Rec is record
272277
A : Integer;
273278
B : Boolean;
274279
end record;
280+
for Rec use record
281+
A at 0 range 0 .. 31;
282+
B at 0 range 32 .. 33;
283+
end record;
275284
for Rec'Bit_Order use System.High_Order_First;
276285
for Rec'Scalar_Storage_Order use System.High_Order_First;
277286
278-
type Ar is array (1 .. 1000) of Boolean;
279-
for Ar'Scalar_Storage_Order use System.Low_Order_First;
280-
281287
-- using Ada 2012 aspects
282-
type Rec is record
283-
A : Integer;
284-
B : Boolean;
285-
end record with
286-
Bit_Order => High_Order_First,
287-
Scalar_Storage_Order => High_Order_First;
288-
289288
type Ar is array (1 .. 1000) of Boolean with
290-
Scalar_Storage_Order => Low_Order_First;
289+
Scalar_Storage_Order => System.Low_Order_First;
291290
292291
--------------------------
293292
Change of Representation
294293
--------------------------
295294

296-
* Explicit conversion can be used to change representation
295+
* Explicit new type can be used to set representation
297296
* Very useful to unpack data from file/hardware to speed up references
298297

299298
.. code:: Ada
@@ -411,9 +410,9 @@ Volatile
411410
pragma Volatile(Volatile_U16);
412411
type Volatile_U32 is mod 2**32 with Volatile; -- Ada 2012
413412
414-
* Volatile means that the exact sequence of reads and writes of an object indicated in the source code must be respected in the generated code.
413+
* The exact sequence of reads and writes from the source code must appear in the generated code.
415414

416-
- No optimization of reads and writes please!
415+
- No optimization of reads and writes
417416

418417
* Volatile types are passed by-reference.
419418

@@ -424,33 +423,35 @@ Ada Address Example
424423
.. code:: Ada
425424
426425
type Bitfield is array (Integer range <>) of Boolean;
426+
pragma Component_Size (1);
427427
428428
V : aliased Integer; -- object can be referenced elsewhere
429-
Pragma Volatile (V); -- may be updated at any time
429+
pragma Volatile (V); -- may be updated at any time
430430
431431
V2 : aliased Integer;
432-
Pragma Volatile (V2);
432+
pragma Volatile (V2);
433433
434434
V_A : System.Address := V'Address;
435435
V_I : Integer_Address := To_Integer (V_A);
436436
437437
-- This maps directly on to the bits of V
438438
V3 : aliased Bitfield (1 .. V'Size);
439-
For V3'address use V_A; -- overlay
439+
for V3'Address use V_A; -- overlay
440440
441441
V4 : aliased Integer;
442442
-- Trust me, I know what I'm doing, this is V2
443-
For V4'address use To_Address (V_I - 4);
443+
for V4'Address use To_Address (V_I - 4);
444444
445445
--------------------
446446
Aliasing Detection
447447
--------------------
448448

449-
* Aliasing happens when one object has two names
449+
* :dfn:`Aliasing`: multiple objects are accessing the same address
450450

451-
- Two pointers pointing to the same object
452-
- Two references referencing the same object
453-
- Two variables at the same address
451+
- Types can be different
452+
- Two pointers pointing to the same address
453+
- Two references onto the same address
454+
- Two objects at the same address
454455

455456
* :ada:`Var1'Has_Same_Storage (Var2)` checks if two objects occupy exactly the same space
456457
* :ada:`Var'Overlaps_Storage (Var2)` checks if two object are partially or fully overlapping
@@ -483,7 +484,10 @@ Calling Assembly Code
483484
-----------------------
484485

485486
* Calling assembly code is a vendor-specific extension
486-
* GNAT allows passing assembly scripts directly to the linker through `System.Machine_Code.ASM`
487+
* GNAT allows passing assembly with `System.Machine_Code.ASM`
488+
489+
- Handled by the linker directly
490+
487491
* The developer is responsible for mapping variables on temporaries or registers
488492
* See documentation
489493

@@ -500,8 +504,8 @@ Simple Statement
500504
501505
Asm ("halt", Volatile => True);
502506
503-
- Specify `Volatile` to avoid compiler optimization
504-
- GNAT is picky on that point
507+
- You may specify `Volatile` to avoid compiler optimizations
508+
- In general, keep it False unless it created issues
505509

506510
* You can group several instructions
507511

@@ -565,9 +569,9 @@ Mapping Inputs / Outputs on Temporaries
565569

566570
- A constant
567571

568-
* - D
572+
* - g
569573

570-
- edx (on x86)
574+
- global (on x86)
571575

572576
* - a
573577

@@ -591,16 +595,21 @@ Main Rules
591595
* On x86, the assembler uses ``AT&T`` convention
592596

593597
- First operand is source, second is destination
594-
- See GNU assembler manual for details
598+
599+
* See your toolchain's ``as`` assembler manual for syntax
595600

596601
-------------------------------------
597602
Volatile and Clobber ASM Parameters
598603
-------------------------------------
599604

600-
* Volatile |rightarrow| True deactivates optimizations with regards to suppressed instructions
601-
* Clobber |rightarrow| "reg1, reg2, ..." contains the list of registers considered to be "destroyed" by the use of the ASM call
605+
* :ada:`Volatile` |rightarrow| :ada:`True` deactivates optimizations with regards to suppressed instructions
606+
* :ada:`Clobber` |rightarrow| :ada:`"reg1, reg2, ..."` contains the list of registers considered to be "destroyed" by the use of the ASM call
607+
608+
- ``memory`` if the memory is accessed
609+
610+
+ Compiler won't use memory cache in registers across the instruction.
602611

603-
- Use 'memory' if the memory is accessed in an unpredictable fashion. The compiler will not keep memory values cached in registers across the instruction.
612+
- ``cc`` if flags might have changed
604613

605614
-----------------------------------
606615
Instruction Counter Example (x86)
@@ -619,7 +628,7 @@ Instruction Counter Example (x86)
619628
begin
620629
Asm ("rdtsc" & LF,
621630
Outputs =>
622-
(Unsigned_32'Asm_Output ("=d", Low),
631+
(Unsigned_32'Asm_Output ("=g", Low),
623632
Unsigned_32'Asm_Output ("=a", High)),
624633
Volatile => True);
625634
Values := Unsigned_64 (Low) +

0 commit comments

Comments
 (0)