Skip to main content

Exercises 15.5 Programming 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