i need your help troubleshooting. I have a .c file, linked with multiple .S files. when…
- User
i need your help troubleshooting. I have a .c file, linked with multiple .S files. when I am executing the test command that tests all the different mathematical functions with given values, I am receiving a segmentation fault. go through my code and tell me why:
my .c file: #include <stdio.h> int beginProgram(); int add(int n1, int n2); int subtract(int n1, int n2); int multiply(int n1, int n2); int exponentiation(int n1, int n2); int floordivision(int n1, int n2); int bitcounting(int n); int summation(int n1, n2); int factorial(int n); int modulus(int n1, int n2);
int main () { while (1) {
int input; printf ("Welcome to DanBurr Calcutron\n"); printf ("----------------------------\n"); printf ("Press 1 to begin and list all available commands\n"); printf ("Press 9 to exit program\n"); scanf ("%d", &input); if (input == 1) { beginProgram (); } else if (input == 9) { printf ("Exit command executed\n\n"); break; } else continue; }return 0; }
int beginProgram() { while (1) { int input; printf("Press 0 to add two numbers\n"); printf("Press 1 to subtract two numbers\n"); printf("Press 2 to multiply two numbers\n"); printf("Press 3 to get exponentiation of a number\n"); printf("Press 4 to perform floor division of two numbers\n"); printf("Press 5 to perform bitcounting of a number\n"); printf("Press 6 to find integer summation of two numbers\n"); printf("Press 7 to find factorial of a number\n"); printf("Press 8 to perform modulo division of two numbers\n"); printf("Press 9 to go back to main screen\n"); printf("Enter 10 for test command\n\n"); scanf("%d", &input);
if (input == 9) { printf("Exit called code 9\n\n"); break; }
else if (input == 0) { int n1, n2; printf("Enter first number: \n"); scanf("%d", &n1); printf("Enter second number: \n"); scanf("%d", &n2); int result = add(n1, n2); printf("The result is:%d\n\n", result); }
else if (input == 1) { int n1, n2; printf("Enter first (larger) number: \n"); scanf("%d", &n1); printf("Enter second (smaller) number: \n"); scanf("%d", &n2); int result = subtract(n1, n2); printf("The result is:%d\n\n", result); }
else if (input == 2) { int n1, n2; printf("Enter first number: \n"); scanf("%d", &n1); printf("Enter second number: \n"); scanf("%d", &n2); int result = multiply(n1, n2); printf("The result is:%d\n\n", result); }
else if (input == 3) { int n1, n2; printf("Enter base number: \n"); scanf("%d", &n1); printf("Enter power raising the number to: \n"); scanf("%d", &n2); int result = exponentiation(n1, n2); if(result<0){ printf("Illegal arguments. Try again\n\n"); continue; } else printf("The result is: %d\n\n", result); }
else if (input == 4) { int n1, n2; printf("Enter larger number: \n"); scanf("%d", &n1); printf("Enter number dividing the larger number by: \n"); scanf("%d", &n2); int result = floordivision(n1, n2); if(result<0){ printf("Illegal arguments. Try again\n\n"); continue; } else printf("The result is: %d\n\n", result); }
else if (input == 5) {
int n; printf("Enter number to count bits. Number cannot exceed 32 bits: \n"); scanf("%d", &n); int result = bitcounting(n); printf("The result is:%d\n\n", result); }else if (input == 6) {
int n1, n2; printf("Enter starting(smaller) number: \n"); scanf("%d", &n1); printf("Enter ending(larger) number: \n"); scanf("%d", &n2); int result = summation(n1, n2); printf("The result is:%d\n\n", result); }else if (input == 7)
{ int n; printf("Enter positive number to find factorial. Number cannot exceed 12: \n"); scanf("%d", &n); int result = factorial(n); printf("The result is:%d\n\n", result); }else if (input == 8)
{ int n1, n2; printf("Enter larger number: \n"); scanf("%d", &n1); printf("Enter number dividing the larger number by: \n"); scanf("%d", &n2); int result = modulus(n1, n2); if(result<0){ printf("Illegal arguments. Try again\n\n"); continue; } else printf("The result is: %d\n\n", result); }else if (input == 10) { int n1 = add(100, 199); int n2 = subtract(211999, 9876); int n3 = exponentiation(5, 5); int n4 = floordivision(2004, 5); int n5 = bitcounting(0b100101010001011110011); int n6 = summation(10, 100); int n7 = factorial(6);
printf("100 + 199 = %d", n1); printf("211999 - 9876 = %d", n2); printf("5^5 = %d", n3); printf("floor 2004/5 = %d", n4); printf("1s in 100101010001011110011 = %d", n5); printf("sum [10,100] = %d", n6); printf("6! = %d", n7);} else { printf("Wrong input. Please try again\n\n"); continue; }
} return 0; }
my .S files: .syntax unified .align 4 .type add %function .section .text .global add
add: ADD r0, r0, r1 BX lr
.syntax unified .align 4 .type bitcounting %function .section .text .global bitcounting
bitcounting:
PUSH {R4, r5, LR} @ Save registers and link register MOV r5, #0x0 @counter
bitcount_loop: CMP r0, #0x0 BEQ bitcount_end AND r4, r0, #0x1 @extracting first bit in string, storing in r4 CMP r4, #0x1 BLEQ bitcount_increment @if r4=1, counter will be incremented. LSR r0, r0, #0x1 B bitcount_loop
bitcount_increment:
ADD r5, r5, #0x1 BX lr
bitcount_end:
MOV r0, r5 POP {r4, r5, lr} BX lr
.syntax unified .align 4 .type exponentiation %function .section .text .global exponentiation
exponentiation: MOV r0, #0x5 MOV r1, #0x5
CMP r0, #0x0 @ Check if r0=0 BEQ exp_error_check B exp_start
exp_error_check: CMP r1, #0x0 @ Check if r1=0 BNE exp_start MOV r0, #0xFFFFFFFF @if 0^0 condition, error. returns -1 BX lr
exp_start: PUSH {r2, sp, lr} @ To clear r2 once loop is finished MOV r2, #0x1 @ Initialize result to 1 CMP r1, #0x0 @ Compare exponent to 0 BEQ exp_done @ If exponent is 0, return 1
exp_loop: MUL r2, r2, r0 @ Multiply result by base SUB r1, r1, #1 @ Decrement exponent by 1 CMP r1, #0x0 BNE exp_loop @ If exponent is not 0, continue loop
exp_done: MOV r0, r2 @ Move result to r0 for return POP {r2, sp, lr} @ Clear all registers BX lr @ Return
.syntax unified .align 4 .type factorial %function .section .text .global factorial
factorial: CMP r0, #0x0 BEQ baseCase0 BL factorialHelper POP {sp, lr} BX LR
factorialHelper: PUSH {r4, lr} MOV r4, r0 CMP r0, #0x1 BEQ baseCase1 SUB r0, r0, #0x1 BL factorialHelper
baseCase1: MUL r0, r0, r4 POP {r4, lr} BX LR
baseCase0: MOV r0, #0x1 BX LR
.syntax unified .align 4 .type floordivision %function .section .text .global floordivision
floordivision:
cmp r1, #0 @ Compare divisor to 0 bne floordivstart
MOV r0, #0xFFFFFFFF @ If divisor is 0, return -1 BX lrfloordivstart: PUSH {r4, sp, lr} @ To clear registers after returning MOV r4, #0x0 @ To store result
floor_div_loop: cmp r0, r1 @ Compare dividend to divisor blt floor_div_done @ If dividend < divisor, break loop sub r0, r0, r1 @ Subtract divisor from dividend add r4, r4, #1 @ Increment quotient by 1 b floor_div_loop @ Repeat loop
floor_div_done: mov r0, r4 @ Move quotient to r0 for return POP {r4, sp, lr} bx lr @ Return
.syntax unified .align 4 .type modulus %function .section .text .global modulus
modulus: CMP r1, #0x0 @check if dividing by zero. return -1 if yes BEQ modulus_error B modulus_loop
modulus_error: MOV r0, #0xFFFFFFFF POP {sp, lr} BX lr
modulus_loop: CMP r0, r1 @if r0<r1 BLT modulus_end SUB r0, r0, r1 @r0=r0-r1 B modulus_loop
modulus_end: POP {sp, lr} BX lr
.syntax unified .align 4 .type multiply %function .section .text .global multiply
multiply: MUL r0, r0, r1 BX lr
.syntax unified .align 4 .type subtract %function .section .text .global subtract
subtract: CMP r0, r1 @if r0<r1, swap the values BLT subtract_swap B subtract_start
subtract_swap: PUSH {r4} MOV r4, r0 MOV r0, r1 MOV r1, r4 POP {r4} BX lr
subtract_start: SUB r0, r0, r1 BX lr
.syntax unified .align 4 .type summation %function .section .text .global summation
summation:
CMP r0, r1 @if r0>r1, swap BGT sum_swap BEQ sum_equal @if r0==r1, return r0+r1 PUSH {r4, sp, lr} @pushing register to clear them once result is returned B sum_loop
sum_equal: ADD r0, r0, r1 BX lr
sum_swap: PUSH {r4} @pushing temp r4 to clear it once swap is done MOV r4, r0 MOV r0, r1 MOV r1, r4 POP {r4} B summation
sum_loop:
ADD r4, r4, r0 @r4=r4+r0 ADD r0, #0x1 @r0++ CMP r0, r1 @if r0!=r1, loop BLT sum_loop
ADD r4, r4, r1 @to add last number to result MOV r0, r4 POP {r4, sp, lr} BX lr
- Assistant
The segmentation fault might be caused by the missing parameter in the summation function declaration. There is a missing "int" type in the parameter list.
Change the line:
int summation(int n1, n2);to
int summation(int n1, int n2);Another issue I noticed is that you are adding printf statements without newline characters
\nin your test command section. Add\nat the end of each printf statement:printf("100 + 199 = %d\n", n1); printf("211999 - 9876 = %d\n", n2); printf("5^5 = %d\n", n3); printf("floor 2004/5 = %d\n", n4); printf("1s in 100101010001011110011 = %d\n", n5); printf("sum [10,100] = %d\n", n6); printf("6! = %d\n", n7);