mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-20 22:46: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": [
|
||||
"AARCH",
|
||||
"ackward",
|
||||
"argc",
|
||||
"argv",
|
||||
"asciz",
|
||||
"cbnz",
|
||||
"CDLL",
|
||||
"cout",
|
||||
"csel",
|
||||
"dptr",
|
||||
"DTMP",
|
||||
"FCVTAS",
|
||||
"fcvtz",
|
||||
"fildes",
|
||||
|
|
@ -23,6 +26,7 @@
|
|||
"lname",
|
||||
"lseek",
|
||||
"memcpy",
|
||||
"orward",
|
||||
"pimm",
|
||||
"pseudocode",
|
||||
"regs",
|
||||
|
|
@ -35,6 +39,7 @@
|
|||
"strncpy",
|
||||
"struct",
|
||||
"structs",
|
||||
"Woverflow",
|
||||
"wreg",
|
||||
"xreg"
|
||||
],
|
||||
|
|
|
|||
2
.vscode/sftp.json
vendored
2
.vscode/sftp.json
vendored
|
|
@ -5,7 +5,7 @@
|
|||
"port": 2222,
|
||||
"username": "user",
|
||||
"remotePath": "./asm_book",
|
||||
"uploadOnSave": true,
|
||||
"uploadOnSave": false,
|
||||
"useTempFile": false,
|
||||
"openSsh": true,
|
||||
"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.
|
||||
|
||||
## 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.
|
||||
|
||||
|
|
|
|||
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
|
||||
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
|
||||
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:
|
||||
|
||||
```text
|
||||
mov x0, 1000000
|
||||
mov x0, 1000000
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
be redirected, you get this feature for free:
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -12,8 +12,8 @@ A single particle looks like this:
|
|||
|
||||
```c++
|
||||
struct Particle {
|
||||
int32_t line;
|
||||
int32_t column;
|
||||
int32_t line;
|
||||
int32_t column;
|
||||
};
|
||||
```
|
||||
|
||||
|
|
@ -68,11 +68,11 @@ about writing this project.
|
|||
|
||||
```c++
|
||||
struct Particle {
|
||||
int32_t line;
|
||||
int32_t column;
|
||||
void Step();
|
||||
void Render();
|
||||
void Reset();
|
||||
int32_t line;
|
||||
int32_t column;
|
||||
void Step();
|
||||
void Render();
|
||||
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
|
||||
without emitting a new line. Before printing the "\*", check to ensure
|
||||
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).
|
||||
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
|
||||
|
||||
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`.
|
||||
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
|
||||
variable. Once
|
||||
in assembly language you are behind the defenses of the compiler so
|
||||
to speak. You can modify a `const` local variable or parameter to your
|
||||
heart's content. Should you? That's another question. Will it cause harm?
|
||||
It depends.
|
||||
you will [see](./const_test.s) that `foo` is implemented like any other
|
||||
variable. Once in assembly language you are behind the defenses of the
|
||||
compiler so to speak. You can modify a `const` local variable or
|
||||
parameter to your heart's content. Should you? That's another question.
|
||||
Will it cause harm? It depends.
|
||||
|
||||
## What **IS** Enforced
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
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:
|
||||
|
||||
|
|
@ -45,7 +46,6 @@ language.
|
|||
|
||||
[Here is the source code](./fizzbuzz.s).
|
||||
|
||||
The video is long but there is much benefit to be had by watching
|
||||
and listening to another person's process as they write the code.
|
||||
**AND especially** listening and watching to them debug when
|
||||
things go wrong!
|
||||
The video is long but there is much benefit to be had by watching and
|
||||
listening to another person's process as they write the code. **AND
|
||||
especially** listening and watching to them debug when 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
|
||||
|
||||
`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.
|
||||
|
||||
|
|
|
|||
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
|
||||
|
||||
Breakpoint 1, main () at not_backing_up_x30.s:5
|
||||
5 main: ldr x0, =hw
|
||||
5 main: ldr x0, =hw
|
||||
(gdb) n
|
||||
6 bl puts
|
||||
6 bl puts
|
||||
(gdb) n
|
||||
Hello World!
|
||||
7 ret
|
||||
7 ret
|
||||
(gdb) n
|
||||
^C
|
||||
Program received signal SIGINT, Interrupt.
|
||||
main () at not_backing_up_x30.s:7
|
||||
7 ret
|
||||
7 ret
|
||||
```
|
||||
|
||||
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,
|
||||
long p5, long p6, long p7, long p8,
|
||||
long p9) {
|
||||
printf("This example hurts: %ld %ld\n", p8, p9);
|
||||
long p9) {
|
||||
printf("This example hurts: %ld %ld\n", p8, p9);
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
|
@ -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
|
||||
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` 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.
|
||||
|
||||
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).
|
||||
|
||||
|
|
@ -771,7 +787,7 @@ main:
|
|||
ret
|
||||
|
||||
.data
|
||||
HW: .asciz "Hello, World"
|
||||
HW: .asciz "Hello, World"
|
||||
.end
|
||||
```
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
# 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
|
||||
higher level languages*.
|
||||
|
|
@ -12,10 +12,10 @@ this example:
|
|||
|
||||
```c++
|
||||
unsigned int FibonacciInC(unsigned int nthNumber) {
|
||||
if (nthNumber <= 1) {
|
||||
return nthNumber;
|
||||
}
|
||||
return FibonacciInC(nthNumber - 1) + FibonacciInC(nthNumber - 2);
|
||||
if (nthNumber <= 1) {
|
||||
return nthNumber;
|
||||
}
|
||||
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 `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`.
|
||||
|
||||
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
|
||||
|
||||
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".
|
||||
|
||||
|
|
@ -18,7 +25,7 @@ For review, consider this C or C++ code:
|
|||
|
||||
```c
|
||||
if (a >= b) {
|
||||
// CODE BLOCK
|
||||
// CODE BLOCK
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -37,34 +44,41 @@ Now, consider this `while` loop:
|
|||
|
||||
```c
|
||||
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
|
||||
// Assume value of a is in x0 // 1
|
||||
// Assume value of b is in x1 // 2
|
||||
// 3
|
||||
1: cmp x0, x1 // 4
|
||||
ble 2f // 5
|
||||
bgt 2f // 5
|
||||
// CODE BLOCK // 6
|
||||
b 1b // 7
|
||||
// 8
|
||||
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
|
||||
flow chart above.
|
||||
Temporary label `1` on `line 4` is the end point of the red arrow in the
|
||||
right hand flow chart above.
|
||||
|
||||
## 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
|
||||
|
||||
|
|
|
|||
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]
|
||||
61 | bf.c = 345;
|
||||
|
|
||||
^~~
|
||||
^~~
|
||||
```
|
||||
|
||||
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
|
||||
to be `inline` so that would be closer in performance to equivalent
|
||||
code written to use C / C++ bit fields.
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue