Keil Logo

Technical Support

On-Line Manuals

Compiler User Guide

Preface Overview of the Compiler Getting Started with the Compiler Compiler Features Compiler Coding Practices The compiler as an optimizing compiler Compiler optimization for code size versus speed Compiler optimization levels and the debug view Selecting the target processor at compile time Enabling FPU for bare-metal Optimization of loop termination in C code Loop unrolling in C code Compiler optimization and the volatile keyword Code metrics Code metrics for measurement of code size and data Stack use in C and C++ Benefits of reducing debug information in objects Methods of reducing debug information in objects a Guarding against multiple inclusion of header file Methods of minimizing function parameter passing o Returning structures from functions through regist Functions that return the same result when called Comparison of pure and impure functions Recommendation of postfix syntax when qualifying f Inline functions Compiler decisions on function inlining Automatic function inlining and static functions Inline functions and removal of unused out-of-line Automatic function inlining and multifile compilat Restriction on overriding compiler decisions about Compiler modes and inline functions Inline functions in C++ and C90 mode Inline functions in C99 mode Inline functions and debugging Types of data alignment Advantages of natural data alignment Compiler storage of data objects by natural byte a Relevance of natural data alignment at compile tim Unaligned data access in C and C++ code The __packed qualifier and unaligned data access i Unaligned fields in structures Performance penalty associated with marking whole Unaligned pointers in C and C++ code Unaligned Load Register (LDR) instructions generat Comparisons of an unpacked struct, a __packed stru Compiler support for floating-point arithmetic Default selection of hardware or software floating Example of hardware and software support differenc Vector Floating-Point (VFP) architectures Limitations on hardware handling of floating-point Implementation of Vector Floating-Point (VFP) supp Compiler and library support for half-precision fl Half-precision floating-point number format Compiler support for floating-point computations a Types of floating-point linkage Compiler options for floating-point linkage and co Floating-point linkage and computational requireme Processors and their implicit Floating-Point Units Integer division-by-zero errors in C code Software floating-point division-by-zero errors in About trapping software floating-point division-by Identification of software floating-point division Software floating-point division-by-zero debugging New language features of C99 New library features of C99 // comments in C99 and C90 Compound literals in C99 Designated initializers in C99 Hexadecimal floating-point numbers in C99 Flexible array members in C99 __func__ predefined identifier in C99 inline functions in C99 long long data type in C99 and C90 Macros with a variable number of arguments in C99 Mixed declarations and statements in C99 New block scopes for selection and iteration state _Pragma preprocessing operator in C99 Restricted pointers in C99 Additional library functions in C99 Complex numbers in C99 Boolean type and in C99 Extended integer types and functions in floating-point environment access in C99 snprintf family of functions in C99 type-generic math macros in C99 wide character I/O functions in C99 How to prevent uninitialized data from being initi Compiler Diagnostic Messages Using the Inline and Embedded Assemblers of the AR Compiler Command-line Options Language Extensions Compiler-specific Features C and C++ Implementation Details What is Semihosting? Via File Syntax Summary Table of GNU Language Extensions Standard C Implementation Definition Standard C++ Implementation Definition C and C++ Compiler Implementation Limits

Integer division-by-zero errors in C code

4.54 Integer division-by-zero errors in C code

For targets that do not support hardware division instructions (for example SDIV and UDIV), you can trap and identify integer division-by-zero errors with the appropriate C library helper functions, __aeabi_idiv0() and __rt_raise().

Trapping integer division-by-zero errors with __aeabi_idiv0()

You can trap integer division-by-zero errors with the C library helper function __aeabi_idiv0() so that division by zero returns some standard result, for example zero.
Integer division is implemented in code through the C library helper functions __aeabi_idiv() and __aeabi_uidiv(). Both functions check for division by zero.
When integer division by zero is detected, a branch to __aeabi_idiv0() is made. To trap the division by zero, therefore, you only have to place a breakpoint on __aeabi_idiv0().
The library provides two implementations of __aeabi_idiv0(). The default one does nothing, so if division by zero is detected, the division function returns zero. However, if you use signal handling, an alternative implementation is selected that calls __rt_raise(SIGFPE, DIVBYZERO).
If you provide your own version of __aeabi_idiv0(), then the division functions call this function. The function prototype for __aeabi_idiv0() is:
int __aeabi_idiv0(void);
If __aeabi_idiv0() returns a value, that value is used as the quotient returned by the division function.
On entry into __aeabi_idiv0(), the link register LR contains the address of the instruction after the call to the __aeabi_uidiv() division routine in your application code.
The offending line in the source code can be identified by looking up the line of C code in the debugger at the address given by LR.
If you want to examine parameters and save them for postmortem debugging when trapping __aeabi_idiv0, you can use the $Super$$ and $Sub$$ mechanism:
  1. Prefix __aeabi_idiv0() with $Super$$ to identify the original unpatched function __aeabi_idiv0().
  2. Use __aeabi_idiv0() prefixed with $Super$$ to call the original function directly.
  3. Prefix __aeabi_idiv0() with $Sub$$ to identify the new function to be called in place of the original version of __aeabi_idiv0().
  4. Use __aeabi_idiv0() prefixed with $Sub$$ to add processing before or after the original function __aeabi_idiv0().
The following example shows how to intercept __aeabi_div0 using the $Super$$ and $Sub$$ mechanism.
extern void $Super$$__aeabi_idiv0(void);
/* this function is called instead of the original __aeabi_idiv0() */
void $Sub$$__aeabi_idiv0()
{
    // insert code to process a divide by zero
    ...
    // call the original __aeabi_idiv0 function
    $Super$$__aeabi_idiv0();
}

Trapping integer division-by-zero errors with __rt_raise()

By default, integer division by zero returns zero. If you want to intercept division by zero, you can re-implement the C library helper function __rt_raise().
The function prototype for __rt_raise() is:
void __rt_raise(int signal, int type);
If you re-implement __rt_raise(), then the library automatically provides the signal-handling library version of __aeabi_idiv0(), which calls __rt_raise(), then that library version of __aeabi_idiv0() is included in the final image.
In that case, when a divide-by-zero error occurs, __aeabi_idiv0() calls __rt_raise(SIGFPE, DIVBYZERO). Therefore, if you re-implement __rt_raise(), you must check (signal == SIGFPE) && (type == DIVBYZERO) to determine if division by zero has occurred.
Non-ConfidentialPDF file icon PDF versionARM DUI0375H
Copyright © 2007, 2008, 2011, 2012, 2014-2016 ARM. All rights reserved. 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.