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?