added to README for strlen and started work on recursion.

This commit is contained in:
Perry Kivolowitz 2022-08-17 12:35:47 -05:00
parent b81e55218c
commit 05e9aa254a
4 changed files with 62 additions and 120 deletions

View file

@ -0,0 +1,38 @@
# Section 1 - recursion
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*.
## Fibonacci Sequence
The Fibonacci Sequence is one primary example of recursion. Consider
this example:
```c++
unsigned int FibonacciInC(unsigned int nthNumber) {
if (nthNumber <= 1) {
return nthNumber;
}
return FibonacciInC(nthNumber - 1) + FibonacciInC(nthNumber - 2);
}
```
The terminal condition is `nthNumber` less than or equal to 1. If the
parameter is less than or equal to 1, the very same value is returned.
If the parameter is greater than 1, the result is the sum or the
results of the Fibonacci value of one less than the parameter plus the
results of two less than the parameter.
## Recursion Leverages the Stack
Notice that recursion is accomplished by simply calling a function
inside itself. All of the work of implementing recursion is hidden
behind the scenes by the compiler.
Specifically, `nthNumber` and the results of
`FibonacciInC(nthNumber - 1)` is pushed onto (and popped off of) the
stack. The value of `FibonacciInC(nthNumber - 2)` doesn't go on the
stack because its results are used right away.

View file

@ -11,11 +11,11 @@ unsigned int FibonacciInC(unsigned int nthNumber) {
int main() {
printf("In C:\n");
for (unsigned int n = 0; n < 10; n++) {
for (unsigned int n = 0; n < 14; n++) {
printf("Fibonacci number %2d is: %d\n", n, FibonacciInC(n));
}
printf("In assembly language:\n");
for (unsigned int n = 0; n < 10; n++) {
for (unsigned int n = 0; n < 14; n++) {
printf("Fibonacci number %2d is: %d\n", n, Fib(n));
}
return 0;

View file

@ -1,115 +0,0 @@
.arch armv8-a
.file "fib.c"
.text
.align 2
.global FibonacciInC
.type FibonacciInC, %function
FibonacciInC:
.LFB0:
.cfi_startproc
stp x29, x30, [sp, -48]!
.cfi_def_cfa_offset 48
.cfi_offset 29, -48
.cfi_offset 30, -40
mov x29, sp
str x19, [sp, 16]
.cfi_offset 19, -32
str w0, [sp, 44]
ldr w0, [sp, 44]
cmp w0, 1
bhi .L2
ldr w0, [sp, 44]
b .L3
.L2:
ldr w0, [sp, 44]
sub w0, w0, #1
bl FibonacciInC
mov w19, w0
ldr w0, [sp, 44]
sub w0, w0, #2
bl FibonacciInC
add w0, w19, w0
.L3:
ldr x19, [sp, 16]
ldp x29, x30, [sp], 48
.cfi_restore 30
.cfi_restore 29
.cfi_restore 19
.cfi_def_cfa_offset 0
ret
.cfi_endproc
.LFE0:
.size FibonacciInC, .-FibonacciInC
.section .rodata
.align 3
.LC0:
.string "In C:"
.align 3
.LC1:
.string "Fibonacci number %2d is: %d\n"
.align 3
.LC2:
.string "In assembly language:"
.text
.align 2
.global main
.type main, %function
main:
.LFB1:
.cfi_startproc
stp x29, x30, [sp, -32]!
.cfi_def_cfa_offset 32
.cfi_offset 29, -32
.cfi_offset 30, -24
mov x29, sp
adrp x0, .LC0
add x0, x0, :lo12:.LC0
bl puts
str wzr, [sp, 24]
b .L5
.L6:
ldr w0, [sp, 24]
bl FibonacciInC
mov w2, w0
ldr w1, [sp, 24]
adrp x0, .LC1
add x0, x0, :lo12:.LC1
bl printf
ldr w0, [sp, 24]
add w0, w0, 1
str w0, [sp, 24]
.L5:
ldr w0, [sp, 24]
cmp w0, 9
bls .L6
adrp x0, .LC2
add x0, x0, :lo12:.LC2
bl puts
str wzr, [sp, 28]
b .L7
.L8:
ldr w0, [sp, 28]
bl Fib
mov w2, w0
ldr w1, [sp, 28]
adrp x0, .LC1
add x0, x0, :lo12:.LC1
bl printf
ldr w0, [sp, 28]
add w0, w0, 1
str w0, [sp, 28]
.L7:
ldr w0, [sp, 28]
cmp w0, 9
bls .L8
mov w0, 0
ldp x29, x30, [sp], 32
.cfi_restore 30
.cfi_restore 29
.cfi_def_cfa_offset 0
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
.section .note.GNU-stack,"",@progbits

View file

@ -3,19 +3,38 @@
.align 4
Fib: str x30, [sp, -16]!
cmp w0, 1
// If w0 is 0 or 1, take the branch to return w0.
cmp w0, 1
bls 99f
// If we get here, we need to do the recursion.
// Save the parameter on the stack so we can
// get it back between recursions.
str w0, [sp, -16]!
// nthNumber to be stored at 16 off sp
str w0, [sp, -16]! // +1
// Execute Fib(nthNumber - 1)
sub w0, w0, 1
bl Fib
ldr w0, [sp], 16 // temporary
// Fib(n-1) stored at 32 of sp
str w0, [sp, -16]! // +2
// Execute Fib(nthNumber - 2)
ldr w0, [sp, 16]
sub w0, w0, 2
bl Fib
// Restore the results of Fib(nthNumber - 1) and also
// undo the stack change associated with preserving it.
ldr w1, [sp], 16 // +1
add w0, w0, w1
// Undo the stack change due to storing nthNumber
ldr w1, [sp], 16 // 0
99: ldr x30, [sp], 16
ret