## Exercises15.7Programming Exercise

###### 1.

Write a program in assembly language that performs like the C++ program in Listing 15.6.6. That is, it will allow the user to enter the numerator and denominator of a fraction, add $1$ to the fraction, and display the result.

Hint

Consider starting with the solution to Exercise 15.5.1 instead of using the compiler-generated assembly language for the C++ program in Listing 15.6.6.

Solution
@ incFraction.s
@ Gets values from user for a fraction, adds 1
@ to the fraction, and then displays the result.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    x,-12           @ x fraction object
.equ    locals,8        @ space for fraction

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, locals  @ for the structs

@ construct the fraction
bl      fractionConstr

@ get user input
add     r0, fp, x       @ get user values
bl      fractionGet

mov     r1, 1

@ display result
add     r0, fp, x       @ get user values
bl      fractionDisplay

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

@ fractionObject.s
@ field name definitions; requires 8 bytes
@ 2017-09-29: Bob Plantz

@ fraction object definition
.equ    num,0    @ numerator
.equ    den,4    @ denominator

@ fractionConstr.s
@ Construct a fraction object
@ Calling sequence:
@        r0 <- address of fraction variable
@        bl  fractionConstr
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ The code
.text
.align  2
.global fractionConstr
.type   fractionConstr, %function
fractionConstr:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer

mov     r1, 1           @ reasonable numerator
str     r1, [r0, num]

mov     r1, 2           @ reasonable denominator
str     r1, [r0, den]

mov     r0, 0           @ return 0;
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

@ fractionGet.s
@ Gets values for a fraction from keyboard
@ Calling sequence:
@        r0 <- address of the struct
@        bl  getStruct
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ Constant program data
.section .rodata
.align  2
numPrompt:
.asciz        "  Enter numerator: "
denPrompt:
.asciz        "Enter denominator: "

@ The code
.text
.align  2
.global fractionGet
.type   fractionGet, %function
fractionGet:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ pointer to the object

bl      writeStr        @ ask for numerator
bl      getDecInt       @ get it
str     r0, [r4, num]   @ store at this->num

bl      writeStr        @ ask for denominator
bl      getDecInt       @ get it
str     r0, [r4, den]   @ store at this->den

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.align  2
.word   numPrompt
.word   denPrompt

@ fractionAddInt.s
@ Adds an integer to a fraction
@ Assumes (int X den) + num fits into 32 bits.
@ Calling sequence:
@        r0 <- address of the object
@        r1 <- integer to add
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ The code
.text
.align  2
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ this pointer

ldr     r0, [r4, den]   @ get denominator
mul     r2, r1, r0      @ integer X denominator
ldr     r0, [r4, num]   @ get numerator
add     r2, r2, r0      @ numerator + (int X den)
str     r2, [r4, num]   @ save new numerator

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

@ fractionDisplay.s
@ Displays a fraction struct on screen
@ Calling sequence:
@        r0 <- address of the struct
@        bl  fractionDisplay
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ The code
.text
.align  2
.global fractionDisplay
.type   fractionDisplay, %function
fractionDisplay:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ this pointer

ldr     r0, [r4, num]   @ display numerator
bl      putDecInt
mov     r0, '/          @ slash for fraction
bl      putChar
ldr     r0, [r4, den]   @ display denominator
bl      putDecInt
bl      newLine

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

@ putChar.s
@ Writes a character to the standard output (screen).
@ Calling sequence:
@       r0 <- the character
@       bl    putChar
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    STDOUT,1
.equ    theChar,-5     @ for  string
.equ    locals,8       @ space for local var

@ The code
.text
.align  2
.global putChar
.type   putChar, %function
putChar:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, locals

strb    r0, [fp, theChar]  @ write needs address
mov     r0, STDOUT      @ write to screen