Skip to main content

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