mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-21 02:26:59 +08:00
added this
This commit is contained in:
parent
0289755145
commit
d62f2e5de3
9 changed files with 240 additions and 11 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -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"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
BIN
README.pdf
BIN
README.pdf
Binary file not shown.
|
|
@ -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`.
|
||||
|
||||
|
|
|
|||
Binary file not shown.
28
section_1/structs/this.cpp
Normal file
28
section_1/structs/this.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
98
section_1/structs/this.md
Normal file
98
section_1/structs/this.md
Normal file
|
|
@ -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 <stdio.h> // 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!
|
||||
BIN
section_1/structs/this.pdf
Normal file
BIN
section_1/structs/this.pdf
Normal file
Binary file not shown.
98
section_1/structs/this.s
Normal file
98
section_1/structs/this.s
Normal file
|
|
@ -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
|
||||
Loading…
Reference in a new issue