From 535e581f05831b49ce2996033b0dd2fb3fc4d91f Mon Sep 17 00:00:00 2001 From: Perry Kivolowitz Date: Sat, 11 Jun 2022 12:16:27 -0500 Subject: [PATCH] discussion of alignment including little endianess --- section_1/structs/alignment.md | 176 +++++++++++++++++++++++++++++++++ section_1/structs/badges.jpeg | Bin 0 -> 18566 bytes section_1/structs/test01.c | 9 ++ section_1/structs/test02.c | 7 ++ 4 files changed, 192 insertions(+) create mode 100644 section_1/structs/alignment.md create mode 100644 section_1/structs/badges.jpeg create mode 100644 section_1/structs/test01.c create mode 100644 section_1/structs/test02.c diff --git a/section_1/structs/alignment.md b/section_1/structs/alignment.md new file mode 100644 index 0000000..8162e7a --- /dev/null +++ b/section_1/structs/alignment.md @@ -0,0 +1,176 @@ +# Section 1 / Alignment Within Structs + +## Overview + +First, it is important to note that this section applies equally to both classes and structs. +Ignoring methods (which are just functions connected to classes and structs), there is only +a small difference between them. + +In a C++ `class`, members default to `private`. + +In a C++ `struct`, members default to `public`. + +Classes, of course, do not exist in C. + +Hereafter, we will use `class` and `struct` interchangeable. + +In order to access data members of a `struct` you must be able to locate them +relative to the start of the `struct`. If an instance of a `struct` begins at +some address X, the first data member is also located at X so its relative +offset from X is 0. + +In our discussion of alignment, we'll frequently refer to the notion of *offset*. + +## Simple Rule + +*Data members exhibit natural alignment.* + +That is: + +* a `long` will be found at addresses which are a multiple of 8. + +* an `int` will be found at addresses which are a multiple of 4. + +* a `short` will be found at addresses which are even. + +* a `char` can be found anywhere. + +## Impact of the Simple Rule + +Let's assume assume an `int` data member is placed properly at address +some address, let's say 104. This is OK because 104 is a multiple of 4, +the length of an int. + +Suppose a `long` comes next. Does it start at location 108 or 112? + +The answer is 112 even though this leaves a 4 byte gap between the +end of the `int` and the beginning of the `long`. This is because the +natural alignment of a `long` is upon addresses that are multiples of +8, the length of a `long`. + +**Sometimes, there are holes or gaps in a `struct`.** + +Higher level languages like C and C++ know this and produce the right +code. Assembly language programmers have no obligation to stick to no +stinkin' rules. + +![badges](./badges.jpeg) + +If they don't mind writing code that's buggy, that is. + +## Example 1 + +```c +struct { + long a; + short b; + int c; +}; +``` + +Wrong: + +| Offset | Width | Member | +| ------ | ----- | ------ | +| 0 | 8 | a | +| 8 | 2 | b | +| 10 | 4 | c | + +Correct: + +| Offset | Width | Member | +| ------ | ----- | ------ | +| 0 | 8 | a | +| 8 | 2 | b | +| 10 | 2 | -- gap -- | +| 12 | 4 | c | + +Demonstration: + +Given this: + +```c +struct Foo { + long a; + short b; + int c; +}; + +struct Foo Bar = { 0xaaaaaaaaaaaaaaaa, 0xbbbb, 0xcccccccc }; +``` + +A hex dump will show: + +```text +aaaa aaaa aaaa aaaa bbbb 0000 cccc cccc +``` + +Notice the gap filled in which zeros. Note, if this were a +local variable, the zeros might be garbage. + +## Example 2 + +Given this: + +```c +struct Foo { + short a; + char b; + int c; +}; + +struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc }; +``` + +A hex dump will show: + +```text +aaaa 00bb cccc cccc +``` + +Notice there is only one byte of gap before the `int c` +starts. + +*But, but, but - why are the zeros to the left of the b's?* + +This ARM processor is running as a *little endian* machine. + +### Diversion: Little Endian + +Little endian means that within each unit of 2 (above a word), +the **least** significant bytes come first. + +In a little endian machine: + +| Type | Logical Contents | Actual Contents | +| ---- | ---------------- | --------------- | +| `long` | `aabbccddeeff0011` | `0011 eeff ccdd aabb` | + +This shows that a `long` is 8 bytes: + +`aabbccddeeff0011` + +Transpose the two 4 byte groups: + +`eeff0011 aabbccdd` + +Transpose the 2 byte groups: + +`0011 eeff ccdd aabb` + +| Type | Logical Contents | Actual Contents | +| ---- | ---------------- | --------------- | +| `int` | `44556677` | `6677 4455` | + +This shows that an `int` is 4 bytes: + +`44556677` + +Transpose the two 2 byte groups: + +`6677 4455` + +The discussion on little endian is important if you are +looking directly at the contents of memory, like when you +are using `gdb`. + diff --git a/section_1/structs/badges.jpeg b/section_1/structs/badges.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..062cf29b9c64613a4788d8ed38576159f88a6a65 GIT binary patch literal 18566 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