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
