Skip to content
The Chat Archive
gpt-4-0314· OpenAI WildChat-4.8M (AI2)

i need your help troubleshooting. I have a .c file, linked with multiple .S files. when…

  1. 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, int 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\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);
    

    } 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 lr

    floordivstart: 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

  2. Assistant

    Based on the code you provided, I found a mistake in the .S file for the "bitcounting" function. In the "bitcount_increment" section, you have "BX lr" which will return to the caller immediately after incrementing the counter (r5), instead of continuing the loop for bit counting. Here's the corrected "bitcount_increment" section:

    bitcount_increment:
        ADD r5, r5, #0x1
        B bitcount_loop          @ Continue the loop, instead of returning to the caller immediately
    

    After making this change, I would recommend recompiling and testing your code again. If you still encounter any issues, please let me know together with any additional information, and I'll be happy to help.

  3. User

    it is still throwing segmentation fault

  4. Assistant

    I apologize for the inconvenience. I found another issue in your code. In several .S files, you're pushing and popping the stack pointer (sp) unnecessarily. This may cause issues with your stack and eventually lead to segmentation faults. Please remove the stack pointer from PUSH { ... } and POP { ... } lines in your .S files.

    Here's an example from the "exponentiation" function:

    Change this:

    PUSH {r2, sp, lr} 
    

    to this:

    PUSH {r2, lr} 
    

    And this:

    POP {r2, sp, lr}
    

    to this:

    POP {r2, lr}
    

    Please apply these changes to all of your .S files where you have used sp. Once you've made these changes, recompile your code and test it again. If you still encounter any issues, please let me know, and I'll be happy to help.