Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22079

Arithmetic functions written in Inline asm in C program cause Segmentation Fault

$
0
0

Got the following functions for doing multiplication, division and finding a remainder:

#define IS_EQUAL(var_, const_)          ((INT32)(var_) == (INT32)(const_))

// all these functions must use hexadecimals as constants according to syllabus
static inline INT32
math_qmultiply (INT32 num1, INT32 num2)
{
  INT32 retval = 0x0,
        count =  0x0;
  while (num2)
    {
      if (IS_EQUAL ((num2 & 0x1), 0x1))
        {
          retval += num1 << count;
        }
      count++;
      num2 = num2 >> 1;
    }
  return retval;
}

static inline INT32
math_qdivide (INT32 num1, INT32 num2)
{
  if (!num1)
    {
      return 0x0;
    }
  if (!num2)
    {
      return INT_MAX;
    }
  INT32 neg_result = FALSE;
  if (num1 < 0x0)
    {
      num1 = -num1;
      if (num2 < 0x0)
        {
          num2 = -num2;
        }
      else
        {
          neg_result = TRUE;
        }
    }
  else if (num2 < 0x0)
    {
      num2 = -num2;
      neg_result = TRUE;
    }
  INT32 quotient = 0x0;
  while (num1 >= num2)
    {
      num1 -= num2;
      quotient++;
    }
  if (neg_result)
    {
      quotient = -quotient;
    }
  return quotient;
}

static inline INT32
math_qmod (INT32 n1, INT32 n2)
{
  INT32 q = math_qdivide (n1, n2);
  INT32 p = math_qmultiply (q, n2);
  return n1 - p;
}

These three functions are used in the below function:

static inline INT32
find_actual_x_for_char_idx (const INT32 char_idx)
{
  INT32 t1 = math_qdivide (char_idx, FRAME_COLS_COUNT);
  register INT32 divisor = math_qmultiply (FRAME_COLS_COUNT, t1);
  INT32 t2 = math_qmod(char_idx, FRAME_COLS_COUNT);
  register INT32 x = !t2 ? 0x0 : char_idx - divisor;
  return FRAME_TOP_LEFT_X + x;
}

This function produces correct output and works OK.

The problem begins when I change the code of the previous functions to have them like this:

INLINE_ATTRIB INT32
math_qmultiply (INT32 n1, INT32 n2)
{
  INT32 res = 0x0;
  asm volatile(
      "mov eax, %1;""mov ebx, %2;""mul ebx;""mov %0, eax;"
      : "=r" (res)
      : "g" (n1),
      "g" (n2)
      );
  return res;
}

INLINE_ATTRIB INT32
math_qdivide (INT32 n1, INT32 n2)
{
  INT32 res = 0;
  asm volatile(
      "mov eax, %1;""mov ebx, %2;""xor edx, edx;""div ebx;""mov %0, eax;"
      : "=r" (res)
      : "g" (n1),
      "g" (n2)
      );
  return res;
}

INLINE_ATTRIB INT32
math_qmod (INT32 n1, INT32 n2)
{
  INT32 res = 0;
  asm volatile
    ("mov eax, %1;""mov ebx, %2;""xor edx, edx;""div ebx;""mov %0, edx;"
     : "=r" (res)
     : "g" (n1), "g" (n2)
     );
  return res;
}

Now I always SEGMENTATION FAULT, though when I check these functions separately they do division, multiplication and finding the remainder correctly. Can you show me what causes SEGMENTATION FAULT?


Viewing all articles
Browse latest Browse all 22079

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>