Quick introduction to reverse engineering for beginners
Quick introduction to reverse engineering for beginners
Quick introduction to reverse engineering for beginners
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
#define PUSH(low, high) ((void) ((<strong>to</strong>p->lo = (low)), (<strong>to</strong>p->hi = (high)), ++<strong>to</strong>p))<br />
#define POP(low, high) ((void) (--<strong>to</strong>p, (low = <strong>to</strong>p->lo), (high = <strong>to</strong>p->hi)))<br />
#define STACK_NOT_EMPTY (stack < <strong>to</strong>p)<br />
/* Order size using quicksort. This implementation incorporates<br />
four optimizations discussed in Sedgewick:<br />
1. Non-recursive, using an explicit stack of pointer that s<strong>to</strong>re the<br />
next array partition <strong>to</strong> sort. To save time, this maximum amount<br />
of space required <strong>to</strong> s<strong>to</strong>re an array of SIZE_MAX is allocated on the<br />
stack. Assuming a 32-bit (64 bit) integer <strong>for</strong> size_t, this needs<br />
only 32 * sizeof(stack_node) == 256 bytes (<strong>for</strong> 64 bit: 1024 bytes).<br />
Pretty cheap, actually.<br />
2. Chose the pivot element using a median-of-three decision tree.<br />
This reduces the probability of selecting a bad pivot value and<br />
eliminates certain extraneous comparisons.<br />
3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving<br />
insertion sort <strong>to</strong> order the MAX_THRESH items within each partition.<br />
This is a big win, since insertion sort is faster <strong>for</strong> small, mostly<br />
sorted array segments.<br />
4. The larger of the two sub-partitions is always pushed on<strong>to</strong> the<br />
stack first, with the algorithm then concentrating on the<br />
smaller partition. This *guarantees* no more than log (<strong>to</strong>tal_elems)<br />
stack size is needed (actually O(1) in this case)! */<br />
void<br />
_quicksort (void *const pbase, size_t <strong>to</strong>tal_elems, size_t size,<br />
__compar_d_fn_t cmp, void *arg)<br />
{<br />
register char *base_ptr = (char *) pbase;<br />
const size_t max_thresh = MAX_THRESH * size;<br />
if (<strong>to</strong>tal_elems == 0)<br />
/* Avoid lossage with unsigned arithmetic below. */<br />
return;<br />
if (<strong>to</strong>tal_elems > MAX_THRESH)<br />
{<br />
char *lo = base_ptr;<br />
char *hi = &lo[size * (<strong>to</strong>tal_elems - 1)];<br />
stack_node stack[STACK_SIZE];<br />
stack_node *<strong>to</strong>p = stack;<br />
PUSH (NULL, NULL);<br />
while (STACK_NOT_EMPTY)<br />
{<br />
char *left_ptr;<br />
char *right_ptr;<br />
205