Skip to main content
\(\newcommand{\doubler}[1]{2#1} \newcommand{\binary}{\mathtt} \newcommand{\hex}{\mathtt} \newcommand{\octal}{\mathtt} \newcommand{\prog}{\mathtt} \newcommand{\lt}{<} \newcommand{\gt}{>} \newcommand{\amp}{&} \)

Section9.4Programming Exercises

Some of the functions you are asked to write in the following exercises are not complete programs. You can check that you have written a valid function by writing a main function in C that calls the function you have written in assembly language. Compile the main function with the -c option so that you get the corresponding object (.o) file. Assemble your assembly language file. Make sure that you specify the debugging options when compiling/assembling. Use the linking phase of gcc to link the .o files together. Run your program under gdb and set a breakpoint in your assembly language function. (Hint: you can specify the source file name in gdb commands.) Now you can verify that your assembly language function is being called. If the function returns a value, you can print that value in the main function using printf.

1

Enter the program in Listing 9.1.3 and use gdb to make sure it works. Next, change the program so that it returns a non-zero integer. Run it with gdb. What number base does gdb use to display the exit code?

Hint

See Table 2.1.3.

Answer

The exit code is displayed in octal.

2

Write the C function:

/* f.c */
int f(void) {
return 0;
}

in assembly language. Make sure that it assembles with no errors. Use the -S option to compile f.c and compare gcc's assembly language with yours.

Hint
/* test.c
 * A main function to print return values.
 * 2017-09-29: Bob Plantz
 */

#include <stdio.h>
/* Prototype of the called function so the
 * compiler knows how to compile the call
 * to the function. Use your function's name.
 */
int f(void);

int main()
{
   int retvalue;
   
   retvalue = f();
   
   printf("return value = %i\n", retvalue);
   
   return 0;
}
Solution
@ f.s
@ Does nothing but return zero to caller.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global f
        .type   f, %function
f:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, 0           @ return values go in r0

        sub     sp, fp, 0	      @ delete allocated memory
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller
3

Write the C function:

/* g.c */
int g(void) {
return 123;
}

in assembly language. Make sure that it assembles with no errors. Use the -S option to compile g.c and compare gcc's assembly language with yours.

Solution
@ g.s
@ Returns 123 to caller.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global g
        .type   g, %function
g:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, 123         @ return values go in r0

        sub     sp, fp, 0	      @ delete allocated memory
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller
4

Write three assembly language functions that do nothing but return an integer. They should each return different, non-zero, integers. Write a C main function to test your assembly language functions. The main function should capture each of the return values and display them using printf.

Solution
/* checkRetNos.c
 * calls three assembly language functions and
 * prints their return numbers.
 *
 * 2017-09-29: Bob Plantz
 */

#include <stdio.h>
int positiveNumber(void);
int negativeNumber(void);
int maxNumber(void);

int main()
{
  int x;

  x = positiveNumber();
  printf("Here is a positive constant: %i, ", x);

  x = negativeNumber();
  printf("a negative constant: %i, ", x);

  x = maxNumber();
  printf("and the maximum number: %i.\n", x);

  return 0;
}
@ positiveNumber.s
@ Returns +100 to caller.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global positiveNumber
        .type   positiveNumber, %function
positiveNumber:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, 100         @ return +100

        sub     sp, fp, 0	      @ restore stack pointer
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller
@ negativeNumber.s
@ Returns -100 to caller.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global negativeNumber
        .type   negativeNumber, %function
negativeNumber:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, -100        @ return -100

        sub     sp, fp, 0	      @ restore stack pointer
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller
@ maxNumber.s
@ Returns the largest "immediate data" constant to caller,
@ which is 8 bits.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global maxNumber
        .type   maxNumber, %function
maxNumber:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, 0xff        @ only 8 bits available for immediate

        sub     sp, fp, 0	      @ restore stack pointer
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller
5

Write three assembly language functions that do nothing but return a character. They should each return different characters. Write a C main function to test your assembly language functions. The main function should capture each of the return values and display them using printf.

Solution
/*
 * checkRetChars.c
 * calls three assembly language functions and
 * prints their return characters.
 *
 * 2017-09-29: Bob Plantz
 */

#include <stdio.h>
int A(void);
int z(void);
int hashtag(void);

int main()
{
    char aCharacter;

    aCharacter = A();
    printf("Here some characters: %c, ", aCharacter);

    aCharacter = z();
    printf("%c, ", aCharacter);

    aCharacter = hashtag();
    printf("and %c.\n", aCharacter);

    return 0;
}
@ A.s
@ Returns 'A' to caller.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global A
        .type   A, %function
A:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, 'A          @ return 'A'

        sub     sp, fp, 0	      @ restore stack pointer
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller
@ z.s
@ Returns 'z' to caller.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global z
        .type   z, %function
z:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, 'z          @ return 'z'

        sub     sp, fp, 0	      @ restore stack pointer
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller
@ hashtag.s
@ Returns '#' to caller.
@ 2017-09-29: Bob Plantz

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

@ Program code
        .text
        .align  2
        .global hashtag
        .type   hashtag, %function
hashtag:
        str     fp, [sp, -4]!   @ save caller frame pointer
        add     fp, sp, 0       @ establish our frame pointer

        mov     r0, #'#         @ return hashtag

        sub     sp, fp, 0	      @ restore stack pointer
        ldr     fp, [sp], 4     @ restore caller's frame pointer
        bx      lr              @ back to caller