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?
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.
/* 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; }
@ 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.
@ 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
.
/* 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
.
/* * 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