diff --git a/.vscode/settings.json b/.vscode/settings.json index 7cc2622..81ab168 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -49,10 +49,14 @@ "Rypo", "SIZD", "SIZF", + "aabb", + "aabbccdd", "amining", "bitfields", + "ccdd", "dless", "dmore", + "eeff", "fcvtms", "fcvtps", "fcvtta", @@ -70,6 +74,7 @@ "slen", "ssize", "stdinp", + "stinkin", "vless", "vmore" ], diff --git a/README.md b/README.md index aed4c29..54610dd 100644 --- a/README.md +++ b/README.md @@ -275,6 +275,7 @@ knowledge - how cool is that! | 8a | [Alignment](./section_1/structs/alignment.md) | [Link](./section_1/structs/alignment.pdf) | | 8b | [Defining](./section_1/structs/defining.md) | [Link](./section_1/structs/defining.pdf) | | 8c | [Using](./section_1/structs/using.md) | [Link](./section_1/structs/using.pdf) | +| 8d | [What is "this"](./section_1/structs/this.md) | [Link](./section_1/structs/this.pdf) | | 9 | [`const`](./section_1/const/README.md) | [Link](./section_1/const/README.pdf) | ### Section 2 - Floating Point @@ -410,7 +411,7 @@ please reach out. Also, check out [Get Off My L@wn](https://www.amazon.com/Get-Off-My-Zombie-Novel-ebook/dp/B00DQ26J8G), -a Zombie novel for coders. +a Zombie novel for coders. You read that right... elite programmer Doug Handsman retires to his wife Ruth Ann's native northern Wisconsin. And then, well, the diff --git a/README.pdf b/README.pdf index bd011b3..5a2b002 100644 Binary files a/README.pdf and b/README.pdf differ diff --git a/section_1/structs/alignment.md b/section_1/structs/alignment.md index 8162e7a..19f4a31 100644 --- a/section_1/structs/alignment.md +++ b/section_1/structs/alignment.md @@ -62,9 +62,9 @@ If they don't mind writing code that's buggy, that is. ```c struct { - long a; - short b; - int c; + long a; + short b; + int c; }; ``` @@ -91,9 +91,9 @@ Given this: ```c struct Foo { - long a; - short b; - int c; + long a; + short b; + int c; }; struct Foo Bar = { 0xaaaaaaaaaaaaaaaa, 0xbbbb, 0xcccccccc }; @@ -114,9 +114,9 @@ Given this: ```c struct Foo { - short a; - char b; - int c; + short a; + char b; + int c; }; struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc }; @@ -173,4 +173,3 @@ Transpose the two 2 byte groups: 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/alignment.pdf b/section_1/structs/alignment.pdf index 6fbde51..33f12d7 100644 Binary files a/section_1/structs/alignment.pdf and b/section_1/structs/alignment.pdf differ diff --git a/section_1/structs/this.cpp b/section_1/structs/this.cpp new file mode 100644 index 0000000..69f5344 --- /dev/null +++ b/section_1/structs/this.cpp @@ -0,0 +1,28 @@ +#include + +class TestClass { + public: + void SetString(char * s); + char * GetString(); + private: + char * _s = nullptr; +}; + +void TestClass::SetString(char * s) { + _s = s; + printf("String set to: %s\n", _s); +} + +char * TestClass::GetString() { + return _s; +} + +char * test_string = (char *) "Test String"; + +TestClass tc; + +int main() { + tc.SetString(test_string); + printf("Stored string is: %s\n", tc.GetString()); + return 0; +} diff --git a/section_1/structs/this.md b/section_1/structs/this.md new file mode 100644 index 0000000..0534884 --- /dev/null +++ b/section_1/structs/this.md @@ -0,0 +1,98 @@ +# Section 1 / What is "this" + +When using an instance of a C++ `class` or `struct`, you know already +that any method you call somehow knows which specific instance you are +using. The exception to *this*, of course, are methods which are declared +as `static` which do *not* know which specific instance you are +referring to - `static` methods are instance-agnostic. + +Like many of the cool features of C++, *this* seemingly magical +self-awareness is accomplished by slight-of-hand. In *this* chapter, we +examine how *this* is done. + +In case the italics used up to now where ever the word *this* has been +used, the slight-of-hand involves the `this` pointer. + +## `this` pointer + +Every non-static method call employs a hidden first parameter. This +parameter is the `this` pointer which points to the specific instance +of the class being used. + +Here is the [source code](./this.cpp) to our test harness: + +```c++ +#include // 1 + // 2 +class TestClass { // 3 + public: // 4 + void SetString(char * s); // 5 + char * GetString(); // 6 + private: // 7 + char * _s = nullptr; // 8 +}; // 9 + // 10 +void TestClass::SetString(char * s) { // 11 + _s = s; // 12 + printf("String set to: %s\n", _s); // 13 +} // 14 + // 15 +char * TestClass::GetString() { // 16 + return _s; // 17 +} // 18 + // 19 +char * test_string = (char *) "Test String"; // 20 + // 21 +TestClass tc; // 22 + // 23 +int main() { // 24 + tc.SetString(test_string); // 25 + printf("Stored string is: %s\n", tc.GetString()); // 26 + return 0; // 27 +} // 28 +``` + +There are no surprises in this code. + +On line 25, when method `SetString()` is called, a specific instance +of the `class` is used, namely the one called `tc`. It looks like there +is only one parameter to the method call. + +On line 26, when method `GetString()` is called, it will return the +a pointer to the very same string that was used in the previous line. + +If compiled with: + +```text +g++ -std=c++11 -O0 -S this.cpp +``` + +an assembly language file called `this.s` will be produced. In it, after +wading through a lot of what seems like gibberish, you will find: + +```text + adrp x8, _test_string@PAGE + ldr x1, [x8, _test_string@PAGEOFF] + adrp x0, _tc@PAGE + add x0, x0, _tc@PAGEOFF + str x0, [sp, #16] ; 8-byte Folded Spill + bl __ZN9TestClass9SetStringEPc +``` + +followed by: + +```text + ldr x0, [sp, #16] ; 8-byte Folded Reload + bl __ZN9TestClass9GetStringEv +``` + +Note: this was built on a Mac M series. The code, if built on Linux, +will be slightly different. + +Notice the address of the string winds up in `x1` **not** in `x0` where +a first parameter ought to have gone. + +What goes in `x0`, i.e. the first parameter slot, is a pointer to the +specific instance of the `class` being used. + +Magic! diff --git a/section_1/structs/this.pdf b/section_1/structs/this.pdf new file mode 100644 index 0000000..d657fe9 Binary files /dev/null and b/section_1/structs/this.pdf differ diff --git a/section_1/structs/this.s b/section_1/structs/this.s new file mode 100644 index 0000000..6a3f2ce --- /dev/null +++ b/section_1/structs/this.s @@ -0,0 +1,98 @@ + .section __TEXT,__text,regular,pure_instructions + .build_version macos, 13, 0 sdk_version 13, 3 + .globl __ZN9TestClass9SetStringEPc ; -- Begin function _ZN9TestClass9SetStringEPc + .p2align 2 +__ZN9TestClass9SetStringEPc: ; @_ZN9TestClass9SetStringEPc + .cfi_startproc +; %bb.0: + sub sp, sp, #48 + .cfi_def_cfa_offset 48 + stp x29, x30, [sp, #32] ; 16-byte Folded Spill + add x29, sp, #32 + .cfi_def_cfa w29, 16 + .cfi_offset w30, -8 + .cfi_offset w29, -16 + stur x0, [x29, #-8] + str x1, [sp, #16] + ldur x8, [x29, #-8] + ldr x9, [sp, #16] + str x9, [x8] + ldr x8, [x8] + mov x9, sp + str x8, [x9] + adrp x0, l_.str@PAGE + add x0, x0, l_.str@PAGEOFF + bl _printf + ldp x29, x30, [sp, #32] ; 16-byte Folded Reload + add sp, sp, #48 + ret + .cfi_endproc + ; -- End function + .globl __ZN9TestClass9GetStringEv ; -- Begin function _ZN9TestClass9GetStringEv + .p2align 2 +__ZN9TestClass9GetStringEv: ; @_ZN9TestClass9GetStringEv + .cfi_startproc +; %bb.0: + sub sp, sp, #16 + .cfi_def_cfa_offset 16 + str x0, [sp, #8] + ldr x8, [sp, #8] + ldr x0, [x8] + add sp, sp, #16 + ret + .cfi_endproc + ; -- End function + .globl _main ; -- Begin function main + .p2align 2 +_main: ; @main + .cfi_startproc +; %bb.0: + sub sp, sp, #48 + .cfi_def_cfa_offset 48 + stp x29, x30, [sp, #32] ; 16-byte Folded Spill + add x29, sp, #32 + .cfi_def_cfa w29, 16 + .cfi_offset w30, -8 + .cfi_offset w29, -16 + mov w8, #0 + stur w8, [x29, #-8] ; 4-byte Folded Spill + stur wzr, [x29, #-4] + adrp x8, _test_string@PAGE + ldr x1, [x8, _test_string@PAGEOFF] + adrp x0, _tc@PAGE + add x0, x0, _tc@PAGEOFF + str x0, [sp, #16] ; 8-byte Folded Spill + bl __ZN9TestClass9SetStringEPc + ldr x0, [sp, #16] ; 8-byte Folded Reload + bl __ZN9TestClass9GetStringEv + mov x8, sp + str x0, [x8] + adrp x0, l_.str.2@PAGE + add x0, x0, l_.str.2@PAGEOFF + bl _printf + ldur w0, [x29, #-8] ; 4-byte Folded Reload + ldp x29, x30, [sp, #32] ; 16-byte Folded Reload + add sp, sp, #48 + ret + .cfi_endproc + ; -- End function + .section __TEXT,__cstring,cstring_literals +l_.str: ; @.str + .asciz "String set to: %s\n" + +l_.str.1: ; @.str.1 + .asciz "Test String" + + .section __DATA,__data + .globl _test_string ; @test_string + .p2align 3 +_test_string: + .quad l_.str.1 + + .globl _tc ; @tc +.zerofill __DATA,__common,_tc,8,3 + .section __TEXT,__cstring,cstring_literals +l_.str.2: ; @.str.2 + .asciz "Stored string is: %s\n" + +.subsections_via_symbols