mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-21 00:26:46 +08:00
updated markdownlint problems plus error in while
This commit is contained in:
parent
87ca33264a
commit
d3fea6487b
35 changed files with 96 additions and 56 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -1,13 +1,16 @@
|
||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"AARCH",
|
"AARCH",
|
||||||
|
"ackward",
|
||||||
"argc",
|
"argc",
|
||||||
"argv",
|
"argv",
|
||||||
"asciz",
|
"asciz",
|
||||||
"cbnz",
|
"cbnz",
|
||||||
|
"CDLL",
|
||||||
"cout",
|
"cout",
|
||||||
"csel",
|
"csel",
|
||||||
"dptr",
|
"dptr",
|
||||||
|
"DTMP",
|
||||||
"FCVTAS",
|
"FCVTAS",
|
||||||
"fcvtz",
|
"fcvtz",
|
||||||
"fildes",
|
"fildes",
|
||||||
|
|
@ -23,6 +26,7 @@
|
||||||
"lname",
|
"lname",
|
||||||
"lseek",
|
"lseek",
|
||||||
"memcpy",
|
"memcpy",
|
||||||
|
"orward",
|
||||||
"pimm",
|
"pimm",
|
||||||
"pseudocode",
|
"pseudocode",
|
||||||
"regs",
|
"regs",
|
||||||
|
|
@ -35,6 +39,7 @@
|
||||||
"strncpy",
|
"strncpy",
|
||||||
"struct",
|
"struct",
|
||||||
"structs",
|
"structs",
|
||||||
|
"Woverflow",
|
||||||
"wreg",
|
"wreg",
|
||||||
"xreg"
|
"xreg"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
2
.vscode/sftp.json
vendored
2
.vscode/sftp.json
vendored
|
|
@ -5,7 +5,7 @@
|
||||||
"port": 2222,
|
"port": 2222,
|
||||||
"username": "user",
|
"username": "user",
|
||||||
"remotePath": "./asm_book",
|
"remotePath": "./asm_book",
|
||||||
"uploadOnSave": true,
|
"uploadOnSave": false,
|
||||||
"useTempFile": false,
|
"useTempFile": false,
|
||||||
"openSsh": true,
|
"openSsh": true,
|
||||||
"password": "a"
|
"password": "a"
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ ShareAlike — If you remix, transform, or build upon the material, you must dis
|
||||||
|
|
||||||
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
||||||
|
|
||||||
## Notices:
|
## Notices
|
||||||
|
|
||||||
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
|
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
|
||||||
|
|
||||||
|
|
|
||||||
BIN
LICENSE.pdf
BIN
LICENSE.pdf
Binary file not shown.
|
|
@ -58,7 +58,7 @@ information about Apple Silicon assembly language programming.
|
||||||
|
|
||||||
You'll notice that we make use of the C-runtime directly rather than
|
You'll notice that we make use of the C-runtime directly rather than
|
||||||
make OS system calls. So, for instance, if we want to call `write()`,
|
make OS system calls. So, for instance, if we want to call `write()`,
|
||||||
we call `write` from the assembly language.
|
we call `write` from the assembly language.
|
||||||
|
|
||||||
This version of the system call `write` is a wrapper function built into
|
This version of the system call `write` is a wrapper function built into
|
||||||
the C-runtime (CRT) which handles the lower level details of performing
|
the C-runtime (CRT) which handles the lower level details of performing
|
||||||
|
|
|
||||||
BIN
README.pdf
BIN
README.pdf
Binary file not shown.
|
|
@ -36,7 +36,7 @@ If the command line argument is *not* given, use a default of 100000.
|
||||||
Remember that all AARCH64 instructions are 32 bits long. An implication of this is you can't simply do:
|
Remember that all AARCH64 instructions are 32 bits long. An implication of this is you can't simply do:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
mov x0, 1000000
|
mov x0, 1000000
|
||||||
```
|
```
|
||||||
|
|
||||||
Since the constant cannot fit along with op codes into four bytes.
|
Since the constant cannot fit along with op codes into four bytes.
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -44,7 +44,7 @@ back "Foo" and a new line. Then I hit ^d so the program exited.
|
||||||
|
|
||||||
### From redirection
|
### From redirection
|
||||||
|
|
||||||
An awsome feature of the command line is the ability to redirect input
|
An awesome feature of the command line is the ability to redirect input
|
||||||
and output. Since the program simply reads from `stdin`, and `stdin` can
|
and output. Since the program simply reads from `stdin`, and `stdin` can
|
||||||
be redirected, you get this feature for free:
|
be redirected, you get this feature for free:
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -12,8 +12,8 @@ A single particle looks like this:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
struct Particle {
|
struct Particle {
|
||||||
int32_t line;
|
int32_t line;
|
||||||
int32_t column;
|
int32_t column;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -68,11 +68,11 @@ about writing this project.
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
struct Particle {
|
struct Particle {
|
||||||
int32_t line;
|
int32_t line;
|
||||||
int32_t column;
|
int32_t column;
|
||||||
void Step();
|
void Step();
|
||||||
void Render();
|
void Render();
|
||||||
void Reset();
|
void Reset();
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ If the particle's `line` exceeds 24, the particle is `Reset()`.
|
||||||
To draw a particle, `Move()` to its location then print a "\*" all
|
To draw a particle, `Move()` to its location then print a "\*" all
|
||||||
without emitting a new line. Before printing the "\*", check to ensure
|
without emitting a new line. Before printing the "\*", check to ensure
|
||||||
both the `line` and `column` are within the boundaries of the default
|
both the `line` and `column` are within the boundaries of the default
|
||||||
terminal window (i.e. line betweeb 1 and 24 and also column
|
terminal window (i.e. line between 1 and 24 and also column
|
||||||
between 1 and 80).
|
between 1 and 80).
|
||||||
If the particle's position is outside this range, don't print anything.
|
If the particle's position is outside this range, don't print anything.
|
||||||
|
|
||||||
|
|
@ -138,4 +138,3 @@ output to be flushed to the terminal.
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
The solution is [here](./main.s).
|
The solution is [here](./main.s).
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -22,12 +22,11 @@ void Const1() { // 3
|
||||||
|
|
||||||
it is the C++ compiler that enforces the immutable nature of `foo`.
|
it is the C++ compiler that enforces the immutable nature of `foo`.
|
||||||
Looking at the assembly language that is produced from this C++ code,
|
Looking at the assembly language that is produced from this C++ code,
|
||||||
you will [see](./const_test.s) that `foo` is implemented like any other
|
you will [see](./const_test.s) that `foo` is implemented like any other
|
||||||
variable. Once
|
variable. Once in assembly language you are behind the defenses of the
|
||||||
in assembly language you are behind the defenses of the compiler so
|
compiler so to speak. You can modify a `const` local variable or
|
||||||
to speak. You can modify a `const` local variable or parameter to your
|
parameter to your heart's content. Should you? That's another question.
|
||||||
heart's content. Should you? That's another question. Will it cause harm?
|
Will it cause harm? It depends.
|
||||||
It depends.
|
|
||||||
|
|
||||||
## What **IS** Enforced
|
## What **IS** Enforced
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
In this chapter we build the classic tech interview question: FizzBuzz.
|
In this chapter we build the classic tech interview question: FizzBuzz.
|
||||||
|
|
||||||
The idea is simple. Write a program that enumerates the integers from 0 to some stopping value, perhaps 100.
|
The idea is simple. Write a program that enumerates the integers from 0
|
||||||
|
to some stopping value, perhaps 100.
|
||||||
|
|
||||||
For each integer:
|
For each integer:
|
||||||
|
|
||||||
|
|
@ -45,7 +46,6 @@ language.
|
||||||
|
|
||||||
[Here is the source code](./fizzbuzz.s).
|
[Here is the source code](./fizzbuzz.s).
|
||||||
|
|
||||||
The video is long but there is much benefit to be had by watching
|
The video is long but there is much benefit to be had by watching and
|
||||||
and listening to another person's process as they write the code.
|
listening to another person's process as they write the code. **AND
|
||||||
**AND especially** listening and watching to them debug when
|
especially** listening and watching to them debug when things go wrong!
|
||||||
things go wrong!
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -191,7 +191,7 @@ Compare `line 14` of the `break` example to the same line in the `continue` exam
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
`for` loops typically contain code ordering different from what one might expect. This is done to save an instruction within the loop. While this doesn't sound like much, consider the case where the loop is executed billions of times. In this case, saving one instruction per loop prevents the execution of a billion instructions.
|
`for` loops typically contain code ordering different from what one might expect. This is done to save an instruction within the loop. While this doesn't sound like much, consider the case where the loop is executed billions of times. In this case, saving one instruction per loop prevents the execution of a billion instructions.
|
||||||
|
|
||||||
The shorter the code block is, the more important it is to save one instruction from within the loop.
|
The shorter the code block is, the more important it is to save one instruction from within the loop.
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -103,17 +103,17 @@ Breakpoint 1 at 0x798: file not_backing_up_x30.s, line 5.
|
||||||
Starting program: /media/psf/Home/asm_book/section_1/funcs/a.out
|
Starting program: /media/psf/Home/asm_book/section_1/funcs/a.out
|
||||||
|
|
||||||
Breakpoint 1, main () at not_backing_up_x30.s:5
|
Breakpoint 1, main () at not_backing_up_x30.s:5
|
||||||
5 main: ldr x0, =hw
|
5 main: ldr x0, =hw
|
||||||
(gdb) n
|
(gdb) n
|
||||||
6 bl puts
|
6 bl puts
|
||||||
(gdb) n
|
(gdb) n
|
||||||
Hello World!
|
Hello World!
|
||||||
7 ret
|
7 ret
|
||||||
(gdb) n
|
(gdb) n
|
||||||
^C
|
^C
|
||||||
Program received signal SIGINT, Interrupt.
|
Program received signal SIGINT, Interrupt.
|
||||||
main () at not_backing_up_x30.s:7
|
main () at not_backing_up_x30.s:7
|
||||||
7 ret
|
7 ret
|
||||||
```
|
```
|
||||||
|
|
||||||
The program hung and had to be killed with ^C. Why?
|
The program hung and had to be killed with ^C. Why?
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -253,12 +253,12 @@ reason):
|
||||||
|
|
||||||
void SillyFunction(long p1, long p2, long p3, long p4,
|
void SillyFunction(long p1, long p2, long p3, long p4,
|
||||||
long p5, long p6, long p7, long p8,
|
long p5, long p6, long p7, long p8,
|
||||||
long p9) {
|
long p9) {
|
||||||
printf("This example hurts: %ld %ld\n", p8, p9);
|
printf("This example hurts: %ld %ld\n", p8, p9);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
SillyFunction(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
SillyFunction(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
3
section_1/hello_world/.markdownlint.json
Normal file
3
section_1/hello_world/.markdownlint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"MD024":false
|
||||||
|
}
|
||||||
|
|
@ -59,7 +59,8 @@ for `c`onsole `out`put. The angle brackets (`<` and `>`) indicate the
|
||||||
include file `iostream` comes from a language or system supplied
|
include file `iostream` comes from a language or system supplied
|
||||||
directory as opposed to an include file written by you.
|
directory as opposed to an include file written by you.
|
||||||
|
|
||||||
For an explanation of what an `include` file is and how it fits into the compilation workflow see [here](https://youtu.be/Iv3psS4n9j8).
|
For an explanation of what an `include` file is and how it fits into the
|
||||||
|
compilation workflow see [here](https://youtu.be/Iv3psS4n9j8).
|
||||||
|
|
||||||
### Line 3
|
### Line 3
|
||||||
|
|
||||||
|
|
@ -222,6 +223,20 @@ fetch what is found at the address specified by `argv`".
|
||||||
That, dear reader, is the address of the string of characters to be
|
That, dear reader, is the address of the string of characters to be
|
||||||
printed. Or, it is a NULL, telling us to stop.
|
printed. Or, it is a NULL, telling us to stop.
|
||||||
|
|
||||||
|
#### Style warning
|
||||||
|
|
||||||
|
Many would argue that the post increment found within the sending of
|
||||||
|
output to `cout` is bad style. We would count ourselves among those who
|
||||||
|
would consider this ill-considered.
|
||||||
|
|
||||||
|
Why? Because a print out isn't a likely place to expect to find
|
||||||
|
something that changes the state of the program. The increment found
|
||||||
|
here can be considered a *side effect*. Side effects are, in general,
|
||||||
|
bad. Try to avoid them. Yes, they can make your code a few lines shorter
|
||||||
|
but this comes at the expense of maintainability.
|
||||||
|
|
||||||
|
So, do as we say, not as we did.
|
||||||
|
|
||||||
### Line 8
|
### Line 8
|
||||||
|
|
||||||
`Line 8` contains a matching brace for the opening brace found line
|
`Line 8` contains a matching brace for the opening brace found line
|
||||||
|
|
@ -464,7 +479,8 @@ the assembly language this looks like:
|
||||||
|
|
||||||
1. Load the memory address of x into a register.
|
1. Load the memory address of x into a register.
|
||||||
|
|
||||||
2. Go out to that memory address and fetch what it contains into a register (a dereference).
|
2. Go out to that memory address and fetch what it contains into a
|
||||||
|
register (a dereference).
|
||||||
|
|
||||||
3. Add one to that value (in the register).
|
3. Add one to that value (in the register).
|
||||||
|
|
||||||
|
|
@ -771,7 +787,7 @@ main:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.data
|
.data
|
||||||
HW: .asciz "Hello, World"
|
HW: .asciz "Hello, World"
|
||||||
.end
|
.end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
||||||
# Section 1 - recursion
|
# Section 1 - recursion
|
||||||
|
|
||||||
Let it be said right from the start:
|
Let it be said right from the start:
|
||||||
|
|
||||||
*Recursion in assembly language is not the ball of joy that it is in
|
*Recursion in assembly language is not the ball of joy that it is in
|
||||||
higher level languages*.
|
higher level languages*.
|
||||||
|
|
@ -12,10 +12,10 @@ this example:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
unsigned int FibonacciInC(unsigned int nthNumber) {
|
unsigned int FibonacciInC(unsigned int nthNumber) {
|
||||||
if (nthNumber <= 1) {
|
if (nthNumber <= 1) {
|
||||||
return nthNumber;
|
return nthNumber;
|
||||||
}
|
}
|
||||||
return FibonacciInC(nthNumber - 1) + FibonacciInC(nthNumber - 2);
|
return FibonacciInC(nthNumber - 1) + FibonacciInC(nthNumber - 2);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -16,7 +16,7 @@ determines how the register is interpreted.
|
||||||
|
|
||||||
* The `x` registers are for `long` integers and addresses.
|
* The `x` registers are for `long` integers and addresses.
|
||||||
* The `w` registers are used for the narrower integer types. While `w`
|
* The `w` registers are used for the narrower integer types. While `w`
|
||||||
stands for *word*, these registers are also used for `short` and
|
stands for *word*, these registers are also used for `short` and
|
||||||
`char`.
|
`char`.
|
||||||
|
|
||||||
The registers used for floating point types (and vector operations) are coincident:
|
The registers used for floating point types (and vector operations) are coincident:
|
||||||
|
|
|
||||||
Binary file not shown.
5
section_1/while/.vscode/settings.json
vendored
Normal file
5
section_1/while/.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"markdownlint.config": {
|
||||||
|
"MD024": false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -2,13 +2,20 @@
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
We have already [covered](../if/README.md) the `if` statement. A `while` loop is exactly the same with the addition of at least one branch and a label. It really is that simple.
|
We have already [covered](../if/README.md) the `if` statement. A `while`
|
||||||
|
loop is exactly the same with the addition of at least one branch and a
|
||||||
|
label. It really is that simple.
|
||||||
|
|
||||||
To illustrate this, here is a flow chart of an `if` statement (on the left) compared to a `while` loop (on the right).
|
To illustrate this, here is a flow chart of an `if` statement (on the
|
||||||
|
left) compared to a `while` loop (on the right).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The closing brace in an `if` statement is indicated by the red arrow head. This isn't a branch, the code flow simply falls through to the statement beyond the closing brace. In the `while` loop, the behavior of the closing brace changes to be that of a branch back to just before the evaluation of the boolean condition (the "Decision").
|
The closing brace in an `if` statement is indicated by the red arrow
|
||||||
|
head. This isn't a branch, the code flow simply falls through to the
|
||||||
|
statement beyond the closing brace. In the `while` loop, the behavior of
|
||||||
|
the closing brace changes to be that of a branch back to just before the
|
||||||
|
evaluation of the boolean condition (the "Decision").
|
||||||
|
|
||||||
A new label is placed before evaluating the "Decision".
|
A new label is placed before evaluating the "Decision".
|
||||||
|
|
||||||
|
|
@ -18,7 +25,7 @@ For review, consider this C or C++ code:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
if (a >= b) {
|
if (a >= b) {
|
||||||
// CODE BLOCK
|
// CODE BLOCK
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -37,34 +44,41 @@ Now, consider this `while` loop:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
while (a >= b) {
|
while (a >= b) {
|
||||||
// CODE BLOCK
|
// CODE BLOCK
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here is the code for the `while` showing the addition of one new label and one new unconditional branch:
|
Here is the code for the `while` showing the addition of one new label
|
||||||
|
and one new unconditional branch:
|
||||||
|
|
||||||
```asm
|
```asm
|
||||||
// Assume value of a is in x0 // 1
|
// Assume value of a is in x0 // 1
|
||||||
// Assume value of b is in x1 // 2
|
// Assume value of b is in x1 // 2
|
||||||
// 3
|
// 3
|
||||||
1: cmp x0, x1 // 4
|
1: cmp x0, x1 // 4
|
||||||
ble 2f // 5
|
bgt 2f // 5
|
||||||
// CODE BLOCK // 6
|
// CODE BLOCK // 6
|
||||||
b 1b // 7
|
b 1b // 7
|
||||||
// 8
|
// 8
|
||||||
2: // 9
|
2: // 9
|
||||||
```
|
```
|
||||||
|
|
||||||
Temporary label `2` on `line 9` takes the place of the line after the closing brace in a `while` loop.
|
Temporary label `2` on `line 9` takes the place of the line after the
|
||||||
|
closing brace in a `while` loop.
|
||||||
|
|
||||||
Temporary label `1` on `line 4` is the end point of the red arrow in the right hand
|
Temporary label `1` on `line 4` is the end point of the red arrow in the
|
||||||
flow chart above.
|
right hand flow chart above.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
A `while` loop is an extension of the `if` statement. A simple `if` contains one conditional branch and one label.
|
A `while` loop is an extension of the `if` statement. A simple `if`
|
||||||
|
contains one conditional branch and one label.
|
||||||
|
|
||||||
A `while` loop contains at least two labels, one conditional branch and one unconditional branch. We acknowledge the possibility that the unconditional branch could be made a conditional one, but this is rarely done in assembly language and impossible in higher level languages like C and C++ since the branch is simply the closing `}`.
|
A `while` loop contains at least two labels, one conditional branch and
|
||||||
|
one unconditional branch. We acknowledge the possibility that the
|
||||||
|
unconditional branch could be made a conditional one, but this is rarely
|
||||||
|
done in assembly language and impossible in higher level languages like
|
||||||
|
C and C++ since the branch is simply the closing `}`.
|
||||||
|
|
||||||
## Questions
|
## Questions
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -35,7 +35,7 @@ should get a warning or an error. For example:
|
||||||
test.c:61:12: warning: unsigned conversion from ‘int’ to ‘volatile unsigned char:5’ changes value from ‘345’ to ‘25’ [-Woverflow]
|
test.c:61:12: warning: unsigned conversion from ‘int’ to ‘volatile unsigned char:5’ changes value from ‘345’ to ‘25’ [-Woverflow]
|
||||||
61 | bf.c = 345;
|
61 | bf.c = 345;
|
||||||
|
|
|
|
||||||
^~~
|
^~~
|
||||||
```
|
```
|
||||||
|
|
||||||
As for the assembly language that bit field will produce, it depends
|
As for the assembly language that bit field will produce, it depends
|
||||||
|
|
@ -54,4 +54,3 @@ store the byte containing our fields.
|
||||||
Note that the C version of the bit field setters could be declared
|
Note that the C version of the bit field setters could be declared
|
||||||
to be `inline` so that would be closer in performance to equivalent
|
to be `inline` so that would be closer in performance to equivalent
|
||||||
code written to use C / C++ bit fields.
|
code written to use C / C++ bit fields.
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in a new issue