mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-23 15:36:45 +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",
|
"Rypo",
|
||||||
"SIZD",
|
"SIZD",
|
||||||
"SIZF",
|
"SIZF",
|
||||||
|
"aabb",
|
||||||
|
"aabbccdd",
|
||||||
"amining",
|
"amining",
|
||||||
"bitfields",
|
"bitfields",
|
||||||
|
"ccdd",
|
||||||
"dless",
|
"dless",
|
||||||
"dmore",
|
"dmore",
|
||||||
|
"eeff",
|
||||||
"fcvtms",
|
"fcvtms",
|
||||||
"fcvtps",
|
"fcvtps",
|
||||||
"fcvtta",
|
"fcvtta",
|
||||||
|
|
@ -70,6 +74,7 @@
|
||||||
"slen",
|
"slen",
|
||||||
"ssize",
|
"ssize",
|
||||||
"stdinp",
|
"stdinp",
|
||||||
|
"stinkin",
|
||||||
"vless",
|
"vless",
|
||||||
"vmore"
|
"vmore"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,7 @@ knowledge - how cool is that!
|
||||||
| 8a | [Alignment](./section_1/structs/alignment.md) | [Link](./section_1/structs/alignment.pdf) |
|
| 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) |
|
| 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) |
|
| 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) |
|
| 9 | [`const`](./section_1/const/README.md) | [Link](./section_1/const/README.pdf) |
|
||||||
|
|
||||||
### Section 2 - Floating Point
|
### Section 2 - Floating Point
|
||||||
|
|
|
||||||
BIN
README.pdf
BIN
README.pdf
Binary file not shown.
|
|
@ -62,9 +62,9 @@ If they don't mind writing code that's buggy, that is.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct {
|
struct {
|
||||||
long a;
|
long a;
|
||||||
short b;
|
short b;
|
||||||
int c;
|
int c;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -91,9 +91,9 @@ Given this:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct Foo {
|
struct Foo {
|
||||||
long a;
|
long a;
|
||||||
short b;
|
short b;
|
||||||
int c;
|
int c;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Foo Bar = { 0xaaaaaaaaaaaaaaaa, 0xbbbb, 0xcccccccc };
|
struct Foo Bar = { 0xaaaaaaaaaaaaaaaa, 0xbbbb, 0xcccccccc };
|
||||||
|
|
@ -114,9 +114,9 @@ Given this:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct Foo {
|
struct Foo {
|
||||||
short a;
|
short a;
|
||||||
char b;
|
char b;
|
||||||
int c;
|
int c;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc };
|
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
|
The discussion on little endian is important if you are
|
||||||
looking directly at the contents of memory, like when you
|
looking directly at the contents of memory, like when you
|
||||||
are using `gdb`.
|
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