Skip to main content

## Exercises15.5Programming Exercise

###### 1.

Modify the program in Listing 15.4.6 so that it allows the user to input values for the two structs.

Hint

Copy the main function from Listing 15.4.6 and get it to work. Then write the function getStruct that will get the values from the user and store them in a struct. I found it useful to create a getChar funtion here. When that is working, replace the display part with a putStruct function.

Solution
@ structPass3.s
@ Allocates two structs and gets values for user for
@ each struct, then displays the values.
@ 2017-09-29: Bob Plantz

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

@ Constants for assembler
.include "theTagStruct.s"  @ theTag struct defs.
.equ    y,-36           @ y struct
.equ    x,-24           @ x struct
.equ    locals,24       @ space for the structs

@ Constant program data
.section .rodata
.align  2
displayX:
.asciz        "x fields:\n"
displayY:
.asciz        "y fields:\n"

@ The program
.text
.align  2
.global main
.type   main, %function
main:
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
sub     sp, sp, locals  @ for the structs

@ fill the x struct
add     r0, fp, x       @ address of x struct
bl      getStruct

@ fill the y struct
add     r0, fp, y       @ address of y struct
bl      getStruct

@ display x struct
ldr     r0, displayXaddr
bl      writeStr
add     r0, fp, x         @ address of x struct
bl      putStruct
bl      newLine

@ display y struct
ldr     r0, displayYaddr
bl      writeStr
add     r0, fp, y         @ address of y struct
bl      putStruct
bl      newLine

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
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
@ addresses of messages
displayXaddr:
.word   displayX
displayYaddr:
.word   displayY

@ getStruct.s
@ Gets values for a theTag struct 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 "theTagStruct.s"  @ theTag struct defs.

@ Constant program data
.section .rodata
.align  2
charPrompt:
.asciz        "Enter a character: "
intPrompt:
.asciz        "Enter an integer: "

@ The program
.text
.align  2
.global getStruct
.type   getStruct, %function
getStruct:
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 struct

ldr     r0, charPromptAddr
bl      writeStr        @ ask for a char
bl      getChar         @ get it
strb    r0, [r4, aChar] @ aStruct->aChar = firstChar;

ldr     r0, intPromptAddr
bl      writeStr        @ ask for a char
bl      getDecInt       @ get it
str     r0, [r4, anInt] @ aStruct->anInt = aNumber;

ldr     r0, charPromptAddr
bl      writeStr        @ ask for a char
bl      getChar         @ get it
strb    r0, [r4, anotherChar] @ aStruct->anotherChar = secondChar;

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
@ addresses of messages
charPromptAddr:
.word   charPrompt
intPromptAddr:
.word   intPrompt

@ putStruct.s
@ Displays values for a theTag struct on screen
@ Calling sequence:
@        r0 <- address of the struct
@        bl  putStruct
@ 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 "theTagStruct.s"  @ theTag struct defs.

@ Constant program data
.section .rodata
.align  2
dispAChar:
.asciz        "         aChar = "
dispAnInt:
.asciz        "         anInt = "
dispOtherChar:
.asciz        "   anotherChar = "

@ The program
.text
.align  2
.global putStruct
.type   putStruct, %function
putStruct:
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 struct

ldr     r0, dispACharAddr  @ display aChar
bl      writeStr
ldrb    r0, [r4, aChar]
bl      putChar
bl      newLine
ldr     r0, dispAnIntAddr  @ display anInt
bl      writeStr
ldr     r0, [r4, anInt]
bl      putDecInt
bl      newLine
ldr     r0, dispOtherCharAddr @ display anotherChar
bl      writeStr
ldrb    r0, [r4, anotherChar]
bl      putChar
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

.align  2
@ addresses of messages
dispACharAddr:
.word   dispAChar
dispAnIntAddr:
.word   dispAnInt
dispOtherCharAddr:
.word   dispOtherChar

@ getChar.s
@ Gets one char from keyboard.
@ Calling sequence:
@       bl getChar
@ returns char in low byte of r0
@ 2017-09-29: Bob Plantz

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

@ Constants for assembler
.equ    maxChars,2      @ max input chars
.equ    inputChar,-12   @ for input chars
.equ    locals,8        @ space for local vars

@ The program
.text
.align  2
.global getChar
.type   getChar, %function
getChar:
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 string

add     r0, fp, inputChar  @ place to store input
mov     r1, maxChars    @ limit input length
bl      readLn

ldrb    r0, [fp, inputChar] @ return inputChar

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