Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
mov eax, DWORD PTR [Divisor]
cdq
mov edi, 100
idiv edi

This code divides Divisorby 100 and places the result in EDX. This is the
most trivial implementation because the modulo is obtained by simply divid-
ing the two values using IDIV, the processor’s signed division instruction.
IDIV’s normal behavior is that it places the result of the division in EAXand
the remainder in EDX, so that code running after this snippet can simply grab
the remainder from EDX. Note that because IDIVis being passed a 32-bit divi-
sor (EDI), it will use a 64-bit dividend in EDX:EAX, which is why the CDQ
instruction is used. It simply converts the value in EAXinto a 64-bit value in
EDX:EAX. For more information on CDQrefer to the type conversions section
later in this chapter.
This approach is good for reversers because it is highly readable, but isn’t
quite the fastest in terms of runtime performance. IDIVis a fairly slow instruc-
tion—one of the slowest in the entire instruction set. This code was generated
by the Microsoft compiler.
Some compilers actually use a multiplication by a reciprocal in order to
determine the modulo (see the section on division).

64-Bit Arithmetic


Modern 32-bit software frequently uses larger-than-32-bit integer data types
for various purposes such as high-precision timers, high-precision signal pro-
cessing, and many others. For general-purpose code that is not specifically
compiled to run on advanced processor enhancements such as SSE, SSE2, and
SSE3, the compiler combines two 32-bit integers and uses specialized
sequences to perform arithmetic operations on them. The following sections
describe how the most common arithmetic operations are performed on such
64-bit data types.
When working with integers larger than 32-bits (without the advanced
SIMD data types), the compiler employs several 32-bit integers to represent
the full operands. In these cases arithmetic can be performed in different ways,
depending on the specific compiler. Compilers that support these larger data
types will include built-in mechanisms for dealing with these data types.
Other compilers might treat these data types as data structures containing sev-
eral integers, requiring the program or a library to provide specific code that
performs arithmetic operations on these data types.

528 Appendix B

22_574817 appb.qxd 3/16/05 8:45 PM Page 528

Free download pdf