justsomeoneelse
justsomeoneelse

Reputation: 49

How ARM Compilers Handle Run Time Errors?

I am trying to generate a run time error such as divide by zero in ARM Cortex M3. I don't know why when I generate divide by zero error system works correctly. However value seems "Infinity"

enter image description here

Does ARM gcc compilers handle these kind of UsageFault errors? I did not implement hardware exception handler yet like Usage Fault, Bus Fault or Mem Manage.

Upvotes: 1

Views: 1894

Answers (3)

ingconti
ingconti

Reputation: 11636

my two cents doing some tests about Arm on Mac and in general exception.

this code:

#include <stdio.h>

int main() {

        int a = 10;
        int b = 0;
        int c = a/b;
        printf("Hello, World!\n");
    return 0;
}

a) on macOS with M1/2 AND Xcode /clang simply set c to 0. No kind of Hw exception or error

b) on linux AND Intel you get usual: Floating point exception (core dumped)

c) (as expected..) using C++ and exception You cannot intercept divide by zero exception (of course on intel.. on Arm never generated)

#include <stdio.h>
#include <exception>
using namespace std;

int main() {

        int a = 10;
        int b = 0;
        int c;
        try {
                c = a/b;
        }
        catch (int e) {
        cout << "AW!  \n" << e << endl;
        }

        cout << ("Hello, World!++ \n");
    return 0;
}

D) note: this can be very confusing if you arrive or go to JAVA, where you can also catch Hw exception.

E) if you set target to x86_64 (even on M1!) You got: "Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)"

Hope can help some others.

Upvotes: 0

fcdt
fcdt

Reputation: 2493

In contrast to , no exception is thrown for if an integer division by zero takes place. There is simply returned 0 as the result

Edit: This only applies to the Cortex-A series. As Jose noted, there is a control register for integer division in the Cortex-M series, as in the case of Floating-point division described in the following. See the link in his answer.


For floating point operations, the Floating-point Control Register (FPSCR for aarch32 or FPCR for aarch64) is decisive for whether an exception is thrown. If the corresponding bit is set there, an exception is thrown, otherwise only a flag in the Floating-Point Status Register (FPSCR in aarch32 or FPSR in aarch64) is set which then indicates the error. This registers can be set via msr and read via mrs.

If no exception is thrown, there are the following rules:

  • infinity divided infinity is NaN
  • zero divided zero is NaN
  • Anything other divided infinity is ±zero
  • Anything other divided zero in ±infinity (sign according to the dividend, this is the case you got in your screenshot)
  • infinity divided anything other is ±infinity
  • zero divided anything other is ±zero

See the pseudocode of FDIV in ARM a64 instruction set architecture.


References:

Upvotes: 1

Jose
Jose

Reputation: 3460

Depending on the architecture the behaviour is different. ARMv6-M doesn't include a divide instruction so it's the software the one to manage this situation (or the compiler, from the C/C++ point of view, it is UB).

On Cortex M3 (ARMv7-M) things are different, there is an UsageFault exception to manage DIVBY0 situations.

Upvotes: 2

Related Questions