mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-23 07:28:04 +08:00
added more to func and start of snow project
This commit is contained in:
parent
0c34e7f4e8
commit
96bb9755db
2 changed files with 77 additions and 15 deletions
53
projects/snow/main.s
Normal file
53
projects/snow/main.s
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
.global main
|
||||||
|
.align 2
|
||||||
|
.text
|
||||||
|
|
||||||
|
.equ NUM_FLAKES, 150
|
||||||
|
|
||||||
|
storm .req x27
|
||||||
|
|
||||||
|
main: stp x29, x30, [sp, -16]!
|
||||||
|
stp x27, x28, [sp, -16]!
|
||||||
|
|
||||||
|
// Seed the RNG with the current time.
|
||||||
|
|
||||||
|
mov w0, wzr
|
||||||
|
bl time
|
||||||
|
bl srand
|
||||||
|
|
||||||
|
// Allocate the storm.
|
||||||
|
|
||||||
|
mov x0, NUM_FLAKES
|
||||||
|
mov x1, Flake.size
|
||||||
|
mul x0, x0, x1
|
||||||
|
bl malloc
|
||||||
|
cbnz x0, 1f
|
||||||
|
|
||||||
|
ldr x0, =bad_malloc
|
||||||
|
bl puts
|
||||||
|
mov w0, 1
|
||||||
|
b bye
|
||||||
|
|
||||||
|
1: mov storm, x0
|
||||||
|
|
||||||
|
|
||||||
|
99: mov x0, storm
|
||||||
|
bl free
|
||||||
|
|
||||||
|
mov w0, wzr
|
||||||
|
|
||||||
|
bye: ldp x27, x28, [sp], 16
|
||||||
|
ldp x20, x30, [sp], 16
|
||||||
|
ret
|
||||||
|
|
||||||
|
ResetFlake:
|
||||||
|
|
||||||
|
|
||||||
|
.data
|
||||||
|
bad_malloc: .asciz "Allocation of flakes has failed"
|
||||||
|
|
||||||
|
.section Flake
|
||||||
|
.struct 0
|
||||||
|
Flake.line: .struct Flake.line + 4
|
||||||
|
Flake.col: .struct Flake.col + 4
|
||||||
|
Flake.size:
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
# Section 1 / Calling and Returning From Functions
|
# Section 1 / Calling and Returning From Functions
|
||||||
|
|
||||||
Calling functions, passing parameters to them and receiving back return values is basic to using `C` and and `C++`. Calling methods (which are functions connected to classes) is similar but with enough differences to warrant its own discussion to be provided later in the chapter on [structs](../struct/structs.md).
|
Calling functions, passing parameters to them and receiving back return
|
||||||
|
values is basic to using `C` and and `C++`. Calling methods (which are
|
||||||
|
functions connected to objects) is similar but with enough differences
|
||||||
|
to warrant its own discussion to be provided later in the chapter on
|
||||||
|
[structs](../struct/structs.md).
|
||||||
|
|
||||||
## Bottom Line Concept
|
## Bottom Line Concept
|
||||||
|
|
||||||
The name of a (non-inline) function is a label to which a branch with link ('bl') can be made.
|
The name of a (non-inline) function is a label to which a branch with
|
||||||
|
link ('bl') can be made.
|
||||||
|
|
||||||
The `bl` instruction is stands for **B**ranch with **L**ink. The **link** concept is what enables a function (or method) to **return** to the instruction after the function call.
|
The `bl` instruction is stands for **B**ranch with **L**ink. The
|
||||||
|
**link** concept is what enables a function (or method) to **return**
|
||||||
*Note: this chapter is only a first look at functions and parameter passing. To fully explore functions and methods, additional knowledge is required.*
|
to the instruction after the call.
|
||||||
|
|
||||||
## A Trivial Function
|
## A Trivial Function
|
||||||
|
|
||||||
|
|
@ -19,7 +24,8 @@ void func() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The function `func()` takes no parameters, does nothing and returns nothing.
|
The function `func()` takes no parameters, does nothing and returns
|
||||||
|
nothing.
|
||||||
|
|
||||||
Here it is in assembly language:
|
Here it is in assembly language:
|
||||||
|
|
||||||
|
|
@ -27,7 +33,9 @@ Here it is in assembly language:
|
||||||
func: ret
|
func: ret
|
||||||
```
|
```
|
||||||
|
|
||||||
Notice that `func` is a label. The only instruction in the function is `ret`. Strictly speaking, the assembly language function might more explicitly look like this in `C`:
|
Notice that `func` is a label. The only instruction in the function is
|
||||||
|
`ret`. Strictly speaking, the assembly language function might more
|
||||||
|
explicitly look like this in `C`:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void func() {
|
void func() {
|
||||||
|
|
@ -47,13 +55,15 @@ This would be done this way in assembly language:
|
||||||
bl func
|
bl func
|
||||||
```
|
```
|
||||||
|
|
||||||
Notice that calling a function **is** a branch. But it is a special branch instruction - *branch-with-link*. It is the *link* that allows the function to `ret`urn.
|
Notice that calling a function **is** a branch. But it is a special
|
||||||
|
branch instruction - *branch-with-link*. Again, it is the *link* that
|
||||||
|
allows the function to `ret`urn.
|
||||||
|
|
||||||
## **bl**
|
## **bl**
|
||||||
|
|
||||||
Branch-with-link computes the address of the instruction following it.
|
Branch-with-link computes the address of the instruction following it.
|
||||||
It places this address into `x30` and then branches to the label
|
It places this address into `x30` and then branches to the label
|
||||||
provides. It makes one link of breadcrumbs to follow to get back
|
provided. It makes one link of breadcrumbs to follow to get back
|
||||||
following a `ret`.
|
following a `ret`.
|
||||||
|
|
||||||
**This is why it is absolutely essential to backup `x30` inside your
|
**This is why it is absolutely essential to backup `x30` inside your
|
||||||
|
|
@ -78,7 +88,7 @@ hw: .asciz "Hello World!" // 10
|
||||||
|
|
||||||
What could possibly go wrong?
|
What could possibly go wrong?
|
||||||
|
|
||||||
Here is a listing from `gdb` as running the program simply
|
Here is a listing from `gdb` since running the program simply
|
||||||
hangs:
|
hangs:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
@ -111,8 +121,8 @@ which it needed to return was sitting in `x30`.
|
||||||
|
|
||||||
Then, `main()` called a function - in this case `puts()` but which
|
Then, `main()` called a function - in this case `puts()` but which
|
||||||
function doesn't matter - it called a function. In doing so, it
|
function doesn't matter - it called a function. In doing so, it
|
||||||
overwrite the address to which `main()` needed to return with the
|
overwrote the address to which `main()` needed to return with the
|
||||||
address of line 7 in the code. That is where `puts()` needed to
|
address of line 7 in the code. That is where `puts()` needs to
|
||||||
return.
|
return.
|
||||||
|
|
||||||
So, when line 7 executes it puts the contents of `x30` into the
|
So, when line 7 executes it puts the contents of `x30` into the
|
||||||
|
|
@ -212,5 +222,4 @@ ReturnsADouble: // 13
|
||||||
```
|
```
|
||||||
|
|
||||||
Note, the use of the floating point move instruction as well as the
|
Note, the use of the floating point move instruction as well as the
|
||||||
single precision and double precision registers. The specification in
|
single precision and double precision registers.
|
||||||
scientific notion is not necessary.
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue