23.03.2013 Views

Quick introduction to reverse engineering for beginners

Quick introduction to reverse engineering for beginners

Quick introduction to reverse engineering for beginners

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!