A Signedness-Agnostic Interval Domain with Congruences and an Implementation for Jakstab

Size: px
Start display at page:

Download "A Signedness-Agnostic Interval Domain with Congruences and an Implementation for Jakstab"

Transcription

1 Bachelor Thesis Anselm Jonas Scholl A Signedness-Agnostic Interval Domain with Congruences and an Implementation for Jakstab May 31, 2016 supervised by: Prof. Dr. Sibylle Schupp Sven Mattsen Hamburg University of Technology (TUHH) Technische Universität Hamburg-Harburg Institute for Software Systems Hamburg

2

3 Eidesstattliche Erklärung Ich versichere an Eides statt, dass ich die vorliegende Bachelorarbeit selbstständig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel verwendet habe. Die Arbeit wurde in dieser oder ähnlicher Form noch keiner Prüfungskommission vorgelegt. Hamburg, den 31. Mai 2016 Anselm Jonas Scholl iii

4

5 Contents Contents 1 Introduction 1 2 Data Flow Analysis Example Widening Signedness-Agnostic Intervals Definition Structure Operations Widening Congruence Classes Definition Operations Signedness-Agnostic Intervals with Congruences Definition Intervals revisited Structure Self-feedback Operations Widening Implementation in Jakstab 49 7 Evaluation Results Related work 57 9 Further work and conclusion 59 v

6

7 List of Figures List of Figures 1.1 Example of wrap-around Example program A long running loop Number circle of 4-bit numbers Joining intervals in a different order yields different results Intervals overlapping at both ends Algorithm to compute a least upper bound for a set of intervals Multiplication of two intervals Utility operators for division and remainder operations Truncating a signedness-agnostic interval Shift operations on intervals The ult and slt functions The uleq and sleq functions Congruence class of x 2 mod 3 on the 4-bit number circle Dispatching arithmetic operations via a jump-table Join operator for sets modulo m Join operator for sets in a given range Inclusion of cc-intervals Example of failed inclusion of cc-intervals Example of an upper bound with congruence information for two intervals Least upper bound of two cc-intervals The infercc function Greatest lower bound of two cc-intervals vii

8

9 1 Introduction The need to analyze binary machine code can arise in many different scenarios. Analyzing malware is only one of these, although maybe the hardest, as the author of the malicious code may has explicitly attempted to hide the real functionality of the code. Others are verification of code, generated by a compiler, against the compiled source code or analyzing closed source programs or device drivers without any known malicious intents. When analyzing malware or closed source software, the objective is to understand the functionality of it. The control flow graph (CFG) provides a starting point for the process as it is later organized into small blocks and subroutines by another analysis or a human, so one can then try to reason about a small fragment of the code instead of the complete program. Verifying that compiled code corresponds to its initial source code can roughly be accomplished by verifying that all reachable paths from the CFG of the source code also exist in the reconstructed CFG of the compiled code. The number of spurious paths here should thereby be as low as possible. The first step in analyzing unknown machine code is determining which parts of the analyzed binary are code and which data. Even if corresponding symbolic information is available, it is generally not reliable, especially if malicious code is analyzed [1]. Generally the control flow of the code has to be reconstructed, as instructions on many modern microprocessors are not bound to start on any aligned addresses and thus every byte may be the potential start of a new instruction. Instructions with different lengths, as for example on modern x86 processors, complicate matters further. Starting at the wrong address could reveal completely different instruction sequences, either missing the real executed instructions or adding unnecessary noise to the already hard task of analyzing the recovered assembly code. Thus, to determine an over-approximation of the executable code that is as small as possible, one has to reconstruct the control flow. Starting from a known entry point an analyzer starts decoding one instruction after another. This is quite straight-forward for most instructions. On most processors arithmetic instructions do not affect the control flow. A direct jump to a known address causes the analysis to continue at the new location, splitting the flow into two paths on conditional jumps. The problem lies in the presence of indirect jumps as it is unclear which instruction is executed next after such a jump, as the position was computed at some point earlier in the program. The simplest case of an indirect jump is the call and return convention on many platforms. Often, the caller writes the address of the next instruction after the subroutine to some known location, for example on the stack or in a dedicated register, and jumps to the subroutine. At its end the subroutine then performs an indirect jump to the address stored on the stack or in the register. To resolve an indirect jump, the set of possible values of the jump target has to be computed. It is crucial not to miss an element of the set, otherwise valid code paths might be missed. For efficiency reasons some kind 1

10 1 Introduction of over-approximation of the set is computed, for example an interval containing all numbers included in the set. uint8 x = 12 x = x if x == 8 then call bad() else call harmless() end Figure 1.1: Example of wrap-around. Naturally one has to be careful to mimic the semantics of the machine that would execute the code, otherwise the analysis will no longer be sound. One example is the duality of addition and subtraction with fixed-precision integers. For example, consider the code in Figure 1.1. If the analysis does not take wrap-around into consideration, it could come to the conclusion that x is unequal to 8 and thus only harmless is called. However, this is not the case and the code will actually call bad. Not accounting for wrap-around thus directly means missing valid execution paths. One problem with intervals, however, is poor precision in the presence of multiplications by a constant. An interval with bounds 10 and 20, multiplied by a constant, for example 4, yields the interval from 40 to 80, assuming no wrap-around happens in that range. The value 41 is now an element of this interval. However, no value between 10 and 20 multiplied by 4 equals 41. In effect, the count of possible numbers in this new interval has grown four times while the count of possible numbers in reality has not grown at all. Such multiplications often happen during address computations, for example, when computing the address of an element in an array. If this now imprecise address is later used to load the value stored in the array, an analysis also has to incorporate 41 as a possible address. If more than one byte is read from that address, the read value consists of parts of the value stored at address 40 and, for example, the value stored at address 44, if a four byte large value is read. This quickly leads to a large over-approximation of the contents of the memory at that address. A possible countermeasure is the introduction of some form of striding or congruence information. For example, one could define an interval with a distance of s between each element [1, p , 18]. The previous example would yield the interval from 40 to 80 with a stride of 4, thus the number 44 would be the second number of the strided interval. Such a strided interval is in effect the reduced product of an interval and an arithmetic congruence. In this thesis, we present an approach to integrate congruence information with signedness-agnostic intervals. We also provide an implementation of the improved intervals for the static binary analysis tool Jakstab [13] and evaluate their usefulness. This docu- 2

11 ment is therefore structured into 9 chapters. Chapter 2 gives a basic introduction to data flow analysis. In Chapter 3, we review classical and signedness-agnostic intervals. Chapter 4 reviews arithmetic congruences and congruence classes. Chapter 5 introduces the abstract domain of signedness-agnostic intervals with congruence information. Chapter 6 describes our implementation in the Jakstab tool, which is then used to evaluate signedness-agnostic intervals with congruences in Chapter 7. In Chapter 8 we discuss previous and related work and in Chapter 9, we present our conclusion and potential further work. 3

12

13 2 Data Flow Analysis As mentioned in the introduction, the crucial step of control flow reconstruction is the computation of all possible jump targets of indirect jumps. Data flow analysis is a general technique to compute these value sets efficiently. However, data flow analysis has much broader applications and is often used in compilers or verification tools. There exist a large number of data flow analyses, for example live variable analysis, constant propagation or sign analysis. Depending on the use case, different analyses are used. A compiler will try to infer whether an assignment is redundant or unused and thus can be omitted, or which variables may be uninitialized, so a warning can be emitted. A verification tool will care more about the latter than the optimization opportunities, but will more likely be interested in the range of possible values a variable can have, e.g., to check the bounds of an array access. As control flow reconstruction depends on computing value sets, any analysis computing such sets will be of interest. 2.1 Example A simple analysis computing sets of possible values is constant propagation [12], which can determine whether a variable will have a constant value, or may have multiple possible values. L 0 : sp = 0xFFFF L 10 : r 3 = 0 L 1 : r 1 = 3 L 11 : goto L 15 if r 2 = 0 L 2 : r 2 = 4 L 12 : r 3 = r 3 + r 1 L 3 : mem[sp] = L 6 L 13 : r 2 = r 2 1 L 4 : sp = sp 1 L 14 : goto L 11 L 5 : goto L 10 L 15 : sp = sp + 1 L 6 : print r 3 L 7 : halt L 16 : goto mem[sp] Figure 2.1: Example program Consider the example program in Figure 2.1: The block from Label L 0 to L 7 sets up a stack, loads some arguments to registers and stores a return address on the stack. Note that while L 6 on the right hand side at Label L 3 is not directly a number, it corresponds to the address of the instruction at Label L 6 at runtime. The program then jumps to something corresponding to a subroutine in most high-level programming languages, 5

14 2 Data Flow Analysis which performs a multiplication by repeated addition of its arguments. As soon as the loop terminates, it loads the return address from the stack, adjusts the stack back to its original state and jumps back to its caller. The caller then prints the result and halts the program. To infer this information using constant propagation, we first define Z = Z { } where Z is the set of possible values of a variable. Z forms a partially ordered set (a set with a transitive, reflexive and anti-symmetric relation) under the relation : x Z : x x, y Z : x y x = y We also define a binary operation, called join or least upper bound, for Z : { x if x = y x y = if x y Let Var denote the set of variables in the analyzed program. Next we define CP = (Var Z ) = (Var Z ) { } to be either, meaning no information is available, or a total mapping from program variables to either a constant or. CP forms a partially ordered set as follows: x CP : x x, y CP : x y v Var : x(v) y(v) Additionally, CP further forms a lattice as we can define a join operator and a meet operator, giving the greatest lower bound of two elements: x if y = x y = y if x = λv.x(v) y(v) otherwise λv.min(x(v), y(v)) if x y v : x y = x(v) y(v) y(v) x(v) otherwise 6

15 2.1 Example Now one has to think about how CP is transformed if an analysis processes a statement in the source code. A function doing such a transformation is called transfer function. For the constant propagation analysis, the only interesting statements are statements that assign a value to a variable; all other statements leave CP unchanged. For an assignment, one first has to replace all variables in the assigned expressions with their mappings and then evaluate the expression. The new value of CP, produced by the transfer function, then maps the assigned variable to the evaluated value. Using these definitions, we can perform the analysis from the point of view of a computer. After program initialization, all variables have undefined values. Thus, the initial value for CP maps each variable to. The first three statements assign constant values to sp, r 1, and r 2. Thus after them, CP 3, which holds at the entry of Label L 3, looks like this: sp 0xFFFF r 1 3 r 2 4 CP 3 = r 3 mem[0]... mem[0xffff] Knowing that sp is constant, the analysis can also infer that the memory at that address has a known constant value after Label L 3. Label L 4 assigns an expression to sp. However, it can be evaluated to a constant value. Thus before the jump, the analysis has inferred the following: sp 0xFFFE r 1 3 r 2 4 r 3 CP 5 = mem[0]... mem[0xfffe] mem[0xffff] L 6 After Label L 5, the analysis continues at Label L 10. At Label L 11, the analysis knows that r 2 will never be 0, thus it only needs to continue at Label L 12. Label L 12 and L 13 produce again constant assignments, thus CP 14 looks like this: 7

16 2 Data Flow Analysis sp 0xFFFE r 1 3 r 2 3 r 3 3 CP 14 = mem[0]... mem[0xfffe] mem[0xffff] L 6 At Label L 14, a jump to an already analyzed label is encountered. Thus, the analysis knows that somewhere in the code, multiple paths to that label exist. Because more than one path exists to Label L 11, the label has to be analyzed again with the knowledge from both paths. To account for the different paths the analysis has to merge the value of CP current with CP 11, computed earlier. We are interested in the values which are definitely constants, thus the merge operation retains only those values as constants which are mapped to the same constant in both inputs. Thus, it will compute something will less or equal many constant valuations compared to each input valuation. Following this, we are interested in the least upper bound of both valuations, or their join: sp 0xFFFE 0xFFFE = 0xFFFE r = 3 r = r = CP 11 CP current = CP 11 = mem[0] =... mem[0xfffe] = mem[0xffff] L 6 L 6 = L 6 The analysis inferred that neither r 2 nor r 3 always has a constant value at Label L 11, as one could easily see from the code in Figure 2.1. With this new knowledge, we now have to analyze Label L 11 again. There we see that the conditional jump can in fact be executed, so the analysis has to remember to analyze the instruction at Label L 15 after it is done with the next instruction and the instructions following it. The assignments at labels L 12 and L 13 now do not change CP anymore as neither r 2 nor r 3 are assigned a constant and are already mapped to in CP. After the jump at Label L 14, the analysis arrives at Label L 11 again, but this time CP is not larger with respect to than the already computed value CP 11. Having CP current CP 11 means that we have reached a fixed point, i.e., that analyzing Label L 11 again would yield something not larger than 8

17 2.2 Widening CP 11. Thus, we can stop here and do hot have to analyze Label L 11 again. Next, we see that we still have to analyze Label L 15, coming from Label L 11, as we, earlier during the analysis, kept that for later. Before continuing, we make sure that CP equals CP 11. This is the case for this example, but for programs with more than a single loop, one easily has multiple program points where an analysis still has to continue, and it is crucial that the right valuation is used to analyze them. sp is incremented at Label L 15. As its value is known, the analysis infers the following for the entry of Label L 16 : sp 0xFFFF r 1 3 r 2 r 3 CP 16 = mem[0]... mem[0xfffe] mem[0xffff] L 6 Now the analysis sees an indirect jump to mem[sp], but CP contains the value of sp as well as mem[sp], so the jump s target can be resolved to Label L 6. Labels L 6 and L 7 are not interesting anymore as these just output the result and halt the program. Note that the analysis could easily be modified to compute another fixed point when it encounters a loop. For example, it could just map all variables to and then iterate as in the example. Then after one iteration something less or equal with respect to would arrive at the loop entry. Thus, the join of mapping all variables to and the new value would map everything to again. So a fixed point can be reached like this after just one iteration. However, it would not be very useful. Instead, it is desirable to compute least fixed point, as, for constant propagation, the least fixed point would map the greatest possible number of variables to constants. The computation of such a least fixed point can be achieved by using a worklist algorithm [20, p. 75]. Such an algorithm can compute the least fixed point as long as the computed information forms a complete lattice, i.e., a lattice with a greatest and a smallest element. 2.2 Widening Computing a fixed point, however, is not always guaranteed to terminate. Consider the code in Figure 2.2. If an analysis tries to compute an interval for the variable x, it will start with the interval containing only the number 1 and on every iteration increase the upper bound of the interval by 1. Depending on the data type of x, either a wrap-around 9

18 2 Data Flow Analysis x = 1 while x > 0 do x = x + 1 end Figure 2.2: A long running loop. occurs after a large number of iterations, and the analysis infers that x ranges from 1 to the maximal positive integer value x can have, or x grows unbounded and the analysis never terminates. Both behaviors are unacceptable for a practical analysis. The problem is that there exist infinitely increasing chains, for example: ( 0, 0 ) ( 0, 1 ) ( 0, 2 )... ( 0, + ) To avoid dealing with such chains, one can use a widening operator [5]. An operator : L L L is a widening operator if and only if: x, y L : x x y y x y { let ln ln if n = 0 = ln 1 l n if n > 0 with l n being an ascending chain. The ascending chain ln eventually stabilizes. While the use of a widening operator may lead to a less precise result, it guarantees termination of an analysis. 10

19 3 Signedness-Agnostic Intervals Classical interval analysis [17, 4] computes a lower bound a and an upper bound b for each program variable x such that a x b holds with a Z { } and b Z {+ }. As it suffices to only store the two bounds for each variable, this representation provides an efficient way to represent large sets of numbers. Naturally, such an analysis requires signedness information, i.e., information about whether a single variable is defined as signed or unsigned. For example, multiplication works quite different on signed and unsigned numbers. While for unsigned arithmetic one has to multiply the lower bounds to get the new lower bound, and the upper bounds to get the new upper bound, signed arithmetic is more complicated. Multiplying two large negative numbers can yield a very large positive number, so an analysis has to distinguish a handful of cases here. Thus, classical interval analysis can only be performed if the signedness of the operands is known. Classical interval analysis also assumes infinite-precision integer arithmetic for program variables. However, for low-level machine code, signedness information is normally not available and arithmetic is performed on fixed-precision integers, making classical interval analysis unsuitable for low-level code. Adapting classical intervals to fixed-precision integer arithmetic would yield intervals including at most the numbers between 0 and 2 w 1 for unsigned intervals or 2 w 1 and 2 w 1 1 for signed intervals (and two s-complement arithmetic). Such intervals still require signedness information to choose the right domain and are in some situations less precise than signedness-agnostic intervals. For example the multiplication of the interval from 0 to 1, denoted ( 0, 1 ), and the number 15 yields the interval ( 0, 15 ). However, if one treats the numbers as 4 bit signed (two s complement) instead of 4 bit unsigned integers, ( 0, 1 ) ( 15, 15 ) turns into ( 0, 1 ) ( 1, 1 ). The product is ( 1, 0 ), which is much more precise than the unsigned interpretation. In a similar way unsigned multiplication can in some cases be more precise than signed multiplication. 3.1 Definition One recent definition of signedness-agnostic intervals [7, 19] is provided by J. Navas, P. Schachte, H. Søndergaard and P. Stuckey. Instead of operating on numbers tied to an interpretation, their signedness-agnostic intervals operate on a range of bit-vectors. This allows it to change the interpretation of a bit-vector on demand or use two different interpretations in a single operation, like multiplication, to compute a more precise result. It also removes the need to know the signedness of most operands as long as the operations preserve the bit-vectors regardless of their signedness. For example, addition, subtraction, and multiplication are independent of their signedness when using two scomplement, while the division and remainder operations return different bit-vectors 11

20 3 Signedness-Agnostic Intervals Figure 3.1: Number circle of 4-bit numbers depending on their signedness. Thus, this information has to be available in the executable code, otherwise a processor running the code would not know which operation to execute. The bit-vectors of signedness-agnostic intervals are lexicographically ordered and form a circle (see Figure 3.1). The bit-vector with all bits set follows the bit-vector with no bit set, resembling the order of bit-vectors of unsigned fixed-precision arithmetic. An interval with the bounds a and b then contains all bit-vectors which lie between a and b in clockwise (increasing) order. A signedness-agnostic interval is an element of the set I n = (W n W n ) = (W n W n ) {, } where W n is the set containing all bit-vectors with n bits. denotes the interval containing everything while denotes the empty interval. Note that both and ( 0 w, 1 w ) (0 n denotes n zero bits) include every w-bit number. However, an analysis should replace an interval containing every w-bit number with, if it produces one, and we assume such a behavior unless otherwise specified. We can check whether a number is an element of an interval: x s = s = (s = ( a, b ) x w a b w a) If the interval contains all numbers, we are done. Otherwise we subtract the lower bound from the number to test and the upper bound. Note that the subtraction happens modulo 2 w, denoted by w. This corresponds to rotating the number circle such that the lower bound corresponds to zero. We then interpret the rotated x and upper bound as unsigned integers and check if x is below or at the upper bound. An signedness-agnostic interval is also closed under complement. Thus, for every interval we can compute an interval containing all numbers not in the interval: 12

21 3.2 Structure = = ( a, b ) = ( b + w 1, a w 1 ) This can be useful, for example, if a program performs a branch of the form if x < 8. If the branch is taken, the analysis knows that x lies in the interval ( 0, 7 ). On the other hand, if the branch is not taken, x lies in the range ( 0, 7 ) = ( 8, 1 w ). 3.2 Structure Signedness-agnostic intervals form a partially ordered set. An interval is less or equal than another interval if all bit-vectors of the smaller interval are included in the greater interval: true s t = false a t b t (c s d s) if s = t = s = t if s = t = if s = ( a, b ) t = ( c, d ) While the set of intervals also seems to form a lattice, this is not quite the case. One problem is that the join of two intervals is not always unique. Consider the two intervals ( 0 n, 0 n ) and ( 10 n 1, 10 n 1 ): Both only contain a single bit-vector, which is on the opposite side of the number circle from the other. Thus, there exist two intervals which include as few as possible other numbers besides these two intervals, namely ( 0 n, 10 n 1 ) and ( 10 n 1, 0 n ). Another problem is that there does not exist an associative join operation for intervals, i.e., a, b, c I n : a (b c) = (a b) c does not hold. For example in Figure 3.2, first joining the two intervals with the largest gap between them can lead to a less precise result. While signedness-agnostic intervals do not form a lattice, one can still implement a quasijoin operation as well as a quasi-meet operation which are quite similar to joinand meet-operations in a lattice [8]. Most importantly, a a b b a b holds. To define, we first define the cardinality of an interval: 13

22 3 Signedness-Agnostic Intervals Figure 3.2: Joining intervals in a different order yields different results. #( ) = 0 #(( a, b )) = b w a + w 1 #( ) = 2 w w is the bit-size of the elements of an interval. + w denotes addition modulo 2 w, i.e., addition as with fixed-precision integers with w bits. Following Gange et al., we can now define an operator: t s ( a, d ) s t = ( c, b ) ( a, d ) ( c, b ) if s t if t s if s = ( a, b ) t = ( c, d ) a t b t c s d s if s = ( a, b ) t = ( c, d ) b t c s if s = ( a, b ) t = ( c, d ) a t d s if s = ( a, b ) t = ( c, d ) (#( b, c ) < #( d, a ) (#( b, c ) = #( d, a ) a c)) otherwise To define an operator, we first compute a list of subintervals contained in both intervals. These are either zero subintervals, in case of no intersection, one subinterval, if an end of one interval intersects with the other interval, or two subintervals, if both ends of the intervals overlap, but not their full ranges. These subintervals can then be joined using to produce the interval containing only elements contained in both 14

23 3.2 Structure Figure 3.3: Intervals overlapping at both ends intervals and as few as possible additional elements. The intersection of two intervals can be computed as follows: {t} {s} {( a, d ), ( c, b )} s t = {s} {t} {( a, d )} {( c, b )} if s = t = if s = t s = if t = if s = ( a, b ) t = ( c, d ) a t b t c s d s if s = ( a, b ) t = ( c, d ) a t b t if s = ( a, b ) t = ( c, d ) c s d s if s = ( a, b ) t = ( c, d ) a t b / t c / s d s if s = ( a, b ) t = ( c, d ) a / t b t c s d / s otherwise Note that we define in terms of and, in difference to Gange et al., who give a definition by cases. However, we believe that their definition under-approximates its result for intervals overlapping at both ends. The definition given by Gange et al. is the following: s t s t = ( c, b ) ( a, d ) s t if s t if t s if s = ( a, b ) t = ( c, d ) a / t b / t c / s d / s if s = ( a, b ) t = ( c, d ) b t c s if s = ( a, b ) t = ( c, d ) a t d s if s = ( a, b ) t = ( c, d ) (#s < #t (#s = #t a c)) otherwise Using this definition to compute ( 14, 11 ) ( 7, 2 ), the forth case is the first case matching 15

24 3 Signedness-Agnostic Intervals the arguments. Thus, ( 7, 11 ) would be the result, ignoring the overlap in the interval ( 14, 2 ). However, we wanted to compute the smallest interval including all elements included in both input intervals. Thus, the correct result would be ( 7, 11 ) ( 14, 2 ) = ( 7, 2 ). 3.3 Operations Having established a basic foundation to be able to use signedness-agnostic intervals in a program analysis, we can now turn our attention to operations on them. Addition and subtraction of two signedness-agnostic intervals can be computed as follows: s + t = ( a + w c, b + w d ) s t = ( a w d, b w c ) if s = t = if s = ( a, b ) t = ( c, d ) #s + #t < 2 w otherwise if s = t = if s = ( a, b ) t = ( c, d ) #s + #t < 2 w otherwise One can easily derive the new extremal bounds from the previous bounds, but has to be careful that both intervals together have less than 2 w elements, otherwise the bounds of the newly created interval would cross each other and give a too small interval. Consider ( 0, 128 )+ 8 ( 0, 128 ). This has to be mapped to, otherwise we get ( , ) = ( 0, 0 ), which is clearly false. Similar cases exist for subtraction. Note that signedness-agnostic intervals are transparent with respect to wrap-around. For example, consider ( 10, 12 ) + (( 8, 8 ) ( 6, 6 )) and (( 10, 12 ) + ( 8, 8 )) ( 6, 6 ) with 4-bit integer arithmetic. Evaluating ( 8, 8 ) ( 6, 6 ) first yields ( 2, 2 ), which can easily be added to ( 10, 12 ). However, first adding ( 8, 8 ) and later subtracting ( 6, 6 ) looses precision with traditional intervals, as they require that the lower bound is smaller or equal than the upper bound. Thus, ( 10, 12 ) + ( 8, 8 ) wraps around, yielding ( 0, 15 ), or. Signedness-agnostic intervals have no problems with a greater lower bound than the upper bound, and thus yield ( 12, 14 ) in both evaluation orders. We can now easily derive unary operations for signedness-agnostic intervals. Negation of an interval s can be reduced to ( 0, 0 ) s. Using this, we can also define the bitwise complement of an interval s, which corresponds to (s + ( 1, 1 )). 16

25 3.3 Operations To multiply two signedness-agnostic intervals, we define the notation of the south and the north pole of an interval. The south pole denotes the point where wrap-around happens for unsigned integers and thus lies in the transition from 1 w to 0 w. The north pole describes the corresponding transition for signed integers and lies in the transition from 01 w 1 to 10 w 1. Gange et al. then define a south pole and a north pole split, which compute a set containing no interval crossing the south pole or north pole, and containing all elements the original interval contained. Additionally, they define an operation cut that splits an interval at the south and the north pole: ssplit(s) = s ( 0 w, 1 w ) nsplit(s) = s ( 01 w 1, 10 w 1 ) cut(s) = {nsplit(u) u ssplit(s)} = (s ( 0 w, 01 w 1 )) (s ( 10 w 1, 1 w )) Note that for the operations of ssplit and nsplit, one may not replace the second arguments with, although both intervals contain the same elements. A different definition yielding the same results is given by Gange et al. The intention of the ssplit, nsplit, and cut operations is to be able to easily handle the different cases, producing a small set of resulting intervals, which then form the final interval. However, as we have seen earlier, the operator is not associative, thus, the order in which we combine the parts of the result can greatly influence the precision of the result. Therefore, it is sensible to define a special join operator for sets, which finds the largest uncovered gap of a set of intervals, and then inverts the gap to yield the smallest interval containing all input intervals. Gange et al. first define an operation gap, which returns the gap between two intervals. The operation assumes that the intervals are sorted in order of lexicographically increasing lower bound: gap(s, t) = { ( c, b ) if s = ( a, b ) t = ( c, d ) b / t c / s otherwise The definition of bigger is straightforward. It checks which interval contains more elements and returns it: { t if #t > #s bigger(s, t) = s otherwise Given these two operations, one can define a generalized operator, which gives a 17

26 3 Signedness-Agnostic Intervals least upper bound of a set of intervals. The algorithm is given in Figure 3.4. First it sorts the input set in order of lexicographically increasing left bound and then performs two sweeps around the number circle. In the first sweep it accumulates all intervals crossing the south pole. In the second iteration it accumulates all intervals into f and the largest gap between two intervals in g. As of the order in which it traverses s, no later interval can actually intersect with a gap discovered that way. Finally, it compares the largest uncovered gap and the inverse of all accumulated intervals and inverts this, thus, yielding the smallest interval containing all intervals. s : s = sort(s) f = g = for e s do if e = (e = ( a, b ) b < u a) then f = f e for e s do g = bigger(g, gap(f, e)) f = f e return bigger(g, f) Figure 3.4: Algorithm to compute a least upper bound for a set of intervals. Note that we simply use instead of the extend function defined by Gange et al., as the latter did return larger results than necessary in certain cases. Also we use < u (unsinged less than) in the first iteration instead of u, as intervals containing only one element should not be handled in the first loop. The cut and operations can then be used to compute the product of two intervals. u and s in Figure 3.5 denote unsigned and signed interval multiplication, respectively, while msb computes the most significant bit of its argument. Thus, multiplication of two intervals computes both the unsigned and the signed interpretation of the multiplication. As multiplication performs the same operations on the bit-vectors, regardless whether it is a signed or unsigned multiplication, one can compute both and only keep the parts which are elements of both results. Splitting the inputs at the points of a possible wraparound avoids having to deal with an argument wrapping around in u and s. We then use to flatten the resulting set of intervals into one interval. Note that we use a different test for overflow than Gange et al., to handle, for example, cases like ( 140, 155 ) 8 ( 26, 29 ). This falls into the third pattern. In their paper they 18

27 3.3 Operations { ( a w c, b w d ) if b d a c < 2 w ( a, b ) u ( c, d ) = otherwise ( a w c, b w d ) if msb(a) = 0 msb(b) = 0 msb(c) = 0 msb(d) = 0 b d a c < 2 w ( b w d, a w c ) if msb(a) = 1 msb(b) = 1 msb(c) = 1 msb(d) = 1 b d a c < 2 w ( a, b ) s ( c, d ) = ( a w d, b w c ) if msb(a) = 1 msb(b) = 1 msb(c) = 0 msb(d) = 0 a d = a w d b c = b w c ( b w c, a w d ) if msb(a) = 0 msb(b) = 0 msb(c) = 1 msb(d) = 1 a d = a w d b c = b w c otherwise s us t = (s u t) (s s t) s t = {m u cut(s), v cut(t), m u us v} Figure 3.5: Multiplication of two intervals. define the condition that b c a d = = = 30 < 2 8 = 256 has to hold. Even if we ignore the negative sign and take the absolute value, the test still holds, thus the result should be ( , ) = ( 220, 190 ). But this does not include = 192. The problem is that the test computes a difference between two products of the lower bound of one interval and the upper bound of the other interval. However, there is no guarantee that both products end up being similar numbers, as in the example, and thus almost eliminate each other. By disallowing any overflow in these cases, we ensure that no elimination can take place. To define quotient and remainder operations we have to differentiate between signed and unsigned operations, as these yield different results for the same inputs. For example, 130 / u 13 yields 13, while 126 / s 13 yields 9, although 130 and 126 have the same bit-vectors when considering 8-bit integers. We first define some utility operators in Figure 3.6. sign(s) computes the sign of an interval and returns 1 if msb(s) = 1, otherwise it returns 1. amb denotes an ambiguous result and is used if the analysis can not constrain 19

28 3 Signedness-Agnostic Intervals ( a, b ) / u ( c, d ) = ( a / u d, b / u c ) ( a / s d, b / s c ) if msb(a) = msb(c) = 0 ( b / s c, a / s d ) if msb(a) = msb(c) = 1 ( a, b ) / s ( c, d ) = ( b / s d, a / s c ) if msb(a) = 0 msb(c) = 1 ( a / s c, b / s d ) if msb(a) = 1 msb(c) = 0 s (s / u t) t if #(s / u t) = 1 ( a, b ) % u ( c, d ) = remn (s, m) if #(t) = 1 m t amb(t) otherwise { s (s /s t) t if #(s / s t) = 1 s % u t = sign(s) amb(sign(t) t) otherwise Figure 3.6: Utility operators for division and remainder operations. the result further. It is defined as: amb(( a, b )) = ( 0, b 1 ) We extend the work of Gange et al. at this point with the rem n function. It is used to give a better approximation if the second argument is a constant. It is defined as follows: rem n (s, 0) = rem n (s, t) = {rem worker (a, b, t) ( a, b ) ssplit(s)} {( a % u t, t 1 ), ( 0, b % u t )} if b a < t a < b b % u t rem worker (a, b, t) = {( a % u t, b % u t )} if b a < t {( 0, t 1 )} otherwise After splitting at the south pole, we first check whether the interval has few enough elements to produce a more precise result than ( 0, t 1 ). If this is the case, we then check where t or a multiple of it lies in the interval. Thus, we compute the first number smaller than b which is divisible by t. If it is still larger than a, we have something similar to, for example, rem n (( 4, 6 ), 5). If this is not the case, we can have something 20

29 3.3 Operations similar to rem n (( 2, 3 ), 5), which corresponds to the second case. Otherwise the interval has enough elements so that every number between 0 and t 1 is a possible result. Using this, we can now define the quotient and remainder operations for intervals: udiv(s, t) = {u / u v u ssplit(s), v ssplit(t), v v ( 0 w 1 1, 1 w )} urem(s, t) = {u % u v u ssplit(s), v ssplit(t), v v ( 0 w 1 1, 1 w )} sdiv(s, t) = {u / s v u cut(s), v cut(t), v v ( 0 w 1 1, 1 w )} srem(s, t) = {u % s v u cut(s), v cut(t), v v ( 0 w 1 1, 1 w )} These operations are almost as defined by Gange et al., the only difference is our use of cut for the signed remainder as opposed to their use of ssplit, which does not handle all cases correctly. To compute bounds for the bitwise operations and, or, and xor, we follow the definitions given by Gange et al. It can be achieved by using the algorithm given by Warren [23, p ]. However, we have to make sure that the intervals do not cross the south pole, as this is assumed by the w, & w, and ˆw operators defined by Warren. s t = {u w v u ssplit(s), v ssplit(t)} s & t = {u & w v u ssplit(s), v ssplit(t)} s ˆ t = {u ˆw v u ssplit(s), v ssplit(t)} Extending an interval by k bits is straightforward and one just has to take care of the new highest bit. The following operations to extend an signedness-agnostic interval to a new bit-size are given by Gange et al.: zext(s, k) = {( 0 k a, 0 k b ) ( a, b ) ssplit(s)} sext(s, k) = {( msb(a) k a, msb(b) k b ) ( a, b ) nsplit(s)} Truncating an interval to k bits is a little bit more complicated. Figure 3.7 shows the definition given by Gange et al. Note that a denotes arithmetic right shift and 21

30 3 Signedness-Agnostic Intervals ( trunc(a, k), trunc(b, k) ) trunc(s, k) = if s = if s = ( a, b ) (a a k = b a k trunc(a, k) trunc(b, k)) ((a a k) w b a k trunc(a, k) > trunc(b, k)) otherwise Figure 3.7: Truncating a signedness-agnostic interval. trunc(a, k) discards all but the lower k bits of a bit-vector. One has then to consider four cases: The input interval is. The upper w k bits of the lower and upper bound are equal. If the lower bound compares less or equal to the upper bound, the interval did only include numbers representable with the new number of bits after removing the upper bits. The upper w k bits of the lower bound are lexicographically ordered directly before these bits of the upper bound. Additionally, the lower k bits of the lower bound are larger than the corresponding bits of the upper bound, thus not every k-bit number is a possible result. For every possible number with the new number of bits, the old interval did include a number which could be truncated to it, thus, has to be returned. One can now define bitwise shifts. First we consider shifts for a fixed number of k bits in Figure 3.8, following the definition given by Gange et al. Using this, one can then easily define shifts by intervals: Intersect the second interval with ( 0, w 1 ) and shift by each number in that interval. As there are at most w such numbers, the number of such shifts has an acceptable upper bound. Then one can use the operator to join all results into a single interval. Depending on the definition of the shift operation of the underlying architecture, one has or has not to account for shifts outside of the range ( 0, w 1 ). If such shifts have a defined behavior, it may be necessary to add an additional element to the set of result intervals. For logical left and right shift, this would be an interval containing only a single 0, for arithmetic right shifts it depends on the first input: A single 0 has to be included if the intersection with ( 0, 01 w 1 ) is not empty, and 1 w has to be included if 22

31 3.3 Operations if s = s k = ( a k, b k ) if ( a, b ) = trunc(s, w k) ( 0, 1 w k 0 k ) otherwise if s = s l k = ( a l k, b l k ) if ( 1 w, 0 w ) s s = ( a, b ) ( 0, 0 k 1 w k ) otherwise if s = s a k = ( a a k, b a k ) if ( 01 w 1, 10 w 1 ) s s = ( a, b ) ( 1 k 0 w k, 0 k 1 w k ) otherwise Figure 3.8: Shift operations on intervals. the intersection with ( 10 w 1, 1 w ) is not empty. Comparing two intervals produces a subset of {f alse, true}. We first split the interval at the north or south pole, depending on the signedness of the comparison. Then we use a small helper function to determine the possible results for each pair of subintervals. s < u t = {ult(u, v) u ssplit(s), v ssplit(t)} s < s t = {slt(u, v) u nsplit(s), v nsplit(t)} s u t = {uleq(u, v) u ssplit(s), v ssplit(t)} s s t = {sleq(u, v) u nsplit(s), v nsplit(t)} To compute ult(u, v) and slt(u, v), given in Figure 3.9, we first compute the intersection of u and v. If it is empty, we take two arbitrary elements from each, for example the lower bounds, and compare them. This relies on the assumption that no interval crosses the south or north pole. If the intersection contains only one interval, then we check three different cases: Are u and v equivalent and have a cardinality of 1? Has u only one element and is it the maximum of the second interval? Has v only one element and is it the minimum of the first interval? In any of these cases, we know that every comparison of individual elements of the 23

32 3 Signedness-Agnostic Intervals intervals will yield f alse. Otherwise, both intervals contain elements which could lead to both true and false as a result. {a < u c} if s t = s = ( a, b ) t = ( c, d ) {false} if s = t #s = 1 ult(s, t) = {false} if s t = 1 s = ( a, a ) a = max(t) {false} if s t = 1 t = ( a, a ) a = min(s) {f alse, true} otherwise {a < s c} if s t = s = ( a, b ) t = ( c, d ) {false} if s = t #s = 1 slt(s, t) = {false} if s t = 1 s = ( a, a ) a = max(t) {false} if s t = 1 t = ( a, a ) a = min(s) {f alse, true} otherwise Figure 3.9: The ult and slt functions. Similary, to check if one interval is less than or equal to another, we first check if they share a common subinterval. If not, we compare one element of the first one to an element of the other interval. Otherwise, if they have an intersection, true will always be a possible result, thus we just need to check whether false is also a valid result. {a u c} if s t = s = ( a, b ) t = ( c, d ) {true} if s = t #s = 1 uleq(s, t) = {true} if s t = 1 s = ( a, a ) a = max(t) {true} if s t = 1 t = ( a, a ) a = min(s) {f alse, true} otherwise {a s c} if s t = s = ( a, b ) t = ( c, d ) {true} if s = t #s = 1 sleq(s, t) = {true} if s t = 1 s = ( a, a ) a = max(t) {true} if s t = 1 t = ( a, a ) a = min(s) {f alse, true} otherwise Figure 3.10: The uleq and sleq functions. 24

33 3.4 Widening 3.4 Widening Similar to classical intervals, one has to perform widening to accelerate convergence of signedness-agnostic intervals. Although there exist no infinitely ascending chains, a chain of length 2 w is still too long for an efficient analysis. Thus, we perform widening similar to Gange et al., but with a small modification: ( u, v ) ( u, y ) ( u, 2v w u + w 1 ) ( u, v ) ( x, y ) = ( x, v ) ( 2u w v w 1, v ) ( x, y ) ( x, x + w 2v w 2u + w 1 ) if ( x, y ) ( u, v ) if #( u, v ) 2 w 1 if ( u, v ) ( x, y ) = ( u, y ) if ( u, v ) ( x, y ) = ( x, v ) if ( u, v ) ( x, y ) otherwise If either operand is, the result is. operand. If one operand is, the result is the other We require that ( u, v ) is a subinterval of ( x, y ) in the fifth case while Gange et al. require that u and v should be an element of ( x, y ). However, this does not guarantee that is an upper-bound operator as defined by Nielson et al. [20]. Thus, we restrict that case to actual subintervals. If ( u, v ) is not a subinterval of ( x, y ), but u as well as v are an element of ( x, y ), every number between 0 and 2 w 1 is included in at least one of the intervals. Thus, is the only possible upper bound. As shown by Gange et al. [8], we have to be careful when performing widening for intervals, as they do not form a lattice. Therefore we follow the strategy described by Gange et al. and perform widening in every iteration if the analysis does not converge after a small number of iterations. 25

34

35 4 Congruence Classes Classical congruence analysis computes properties of the form x {c + mk k Z} with c and m being integer constants. One could also write this as x c mod m meaning x is congruent to c with respect to m. Possible use cases of such information would be automatic vectorization [9, 10] or program verification, e.g. to prove no unaligned reads or writes happen during program execution. One example could look like this: p = 0x100 while p < 0x200 do mem[p] = 0xAABBCCDD p = p + 4 end For this code congruence analysis can infer the property p 0 mod 4 and thus knows the words written to the memory do not overlap. Interval analysis, for example, is unable to infer such properties and would have to assume that 0xAABBCCDD written at one iteration could overlap with 0xAABBCCDD written at another iteration. 4.1 Definition Let a b denote that b is divisible by a, i.e., c Z : b = a c, and x c[m] denote x is congruent to c modulo m, i.e., m (x c). As outlined by P. Granger [9, 10], a congruence class is then defined by a residue c and a modulo m, written c[m]. c[m] spans the set c + m Z where m Z denotes {m n n Z}. Thus c[m] includes all numbers x for which x c[m] holds. One can then define a partial order for congruence classes under the relation : c 1 [m 1 ] c 2 [m 2 ] (m 2 c 1 c 2 ) (m 2 m 1 ) m 2 gcd(c 1 c 2, m1) Thus, a congruence class includes another congruence class if and only if the modulus of the assumed larger class divides the modulus of the assumed smaller class. For example, the set of numbers divisible by 4 is clearly a subset of the numbers divisible by 2, but not a subset of the numbers divisible by 3. Additionally, the difference of the residues has to be an element of the assumed larger congruence class. This is, for example, not the case for 1[4] and 0[4], but it is the case for 2[4] and 0[2]. Following this, one can derive an equality operator for two congruence classes from the 27

36 4 Congruence Classes operator: (c 1 [m 1 ] c 2 [m 2 ]) (c 2 [m 2 ] c 1 [m 1 ]) c 1 [m 1 ] = c 2 [m 2 ] (m 1 = ±m 2 ) (m 2 (c 1 c 2 )) (m 1 = ±m 2 ) (c 1 c 2 mod m 2 ) Thus, two congruence classes are equal if the residues are residues of both congruence classes, and the moduli span the same set of numbers. Given two congruence classes, one can also compute the join of both classes. The residue of the result can be any residue of both input classes as all residues of the inputs have to be residues of the result. The modulus of the result has to divide both moduli of the inputs as well as the difference of their residues, to account for, for example, all elements of 1[4] and 0[4]. Thus, the join operator is defined as: c 1 [m 1 ] c 2 [m 2 ] = c 1 [gcd(m 1, m 2, c 1 c 2 )] 4.2 Operations The sum of a congruence class and a single constant shifts all residues of the class. Thus the congruence class of the sum can be determined by: c 1 + c 2 [m 2 ] = (c 1 + c 2 )[m 2 ] Most of the time the sum of two congruence classes is not exactly representable as a congruence class. For example, {3, 7, 8, 11, 12, 13, 15} 2[4] + 1[5]. Thus, one has to over-approximate the result to still obtain a concise representation of it. For addition, one obtains: c 1 [m 1 ] + c 2 [m 2 ] = (c 1 + c 2 )[gcd(m 1, m 2 )] The new congruence class residue is easily given by the sum of the residues of the input classes. We can then write c 1 as k 1 + m 1 n 1 and c 2 as k 2 + m 2 n 2. By taking the greatest common divisor m of m 1 and m 2 we can write c 1 + c 2 as k 1 + k 2 + m n for some n Z. 28

37 4.2 Operations Figure 4.1: Congruence class of x 2 mod 3 on the 4-bit number circle. As a residue can be written as k + m n, multiplying a congruence class with a constant yields c(k + m n) = c k + c m n for all residues. Thus, the product of a congruence class with a constant is then given by: c 1 c 2 [m 2 ] = (c 1 c 2 )[c 1 m 2 ] To determine the product of two congruence classes, one can compute the product of c 1 = k 1 + m 1 n 1 and c 2 = k 2 + m 2 n 2. This yields (k 1 + m 1 n 1 ) (k 2 + m 2 n 2 ) = k 1 k 2 + k 1 m 2 n 2 + m 1 n 1 k 2 + m 1 n 1 m 2 n 2. Thus, a common factor of k 1 m 2 n 2 + m 1 n 1 k 2 + m 1 n 1 m 2 n 2 is given by gcd(c 1 m 2, m 1 c 2, m 1 m 2 ), yielding the following relation: c 1 [m 1 ] c 2 [m 2 ] = (c 1 c 2 )[gcd(c 1 m 2, m 1 c 2, m 1 m 2 )] Note that the congruence classes assume infinite precision integer arithmetic. For example, correctly implementing addition requires taking care of the wrap-around. As one can see in Figure 4.1, one obtains a gap of three elements for the congruence class 2[3] and 4-bit integer arithmetic. If one would add the constant 3 to it, could wrap around and yield However, is not an element of 5[3]. Thus, we will need to take special care in the next chapter to handle wrap-around correctly, as congruence classes are not sound for fixed-precision arithmetic. 29

38

39 5 Signedness-Agnostic Intervals with Congruences While signedness-agnostic intervals provide a solid foundation to analyze low-level code, they inherently perform badly for simple cases as, for example, a multiplication with a constant. However, such computations arise frequently in address-computations. Consider the following example of a function dispatching operations via a jump-table: enum op_t {ADD = 0, SUB = 1, MUL = 2}; int dispatch(enum op_t op, int a, int b) { static void *tbl[] = {&&handleadd, &&handlesub, &&handlemul}; goto *tbl[op]; handleadd: return a + b; handlesub: return a - b; handlemul: return a * b; } Figure 5.1: Dispatching arithmetic operations via a jump-table. The assembler-code, generated by the code in Figure 5.1, will contain a statement of the form jump mem[0x6000a8 + R1 * 4]. Even if we can infer the bounds ( 0, 2 ) for the register R1, the multiplication by 4 widens them to ( 0, 8 ), leading to 9 possible addresses. 6 of them are invalid and reading a value at such an address would read parts of two values. Thus, the analysis gets very imprecise at its best, or can not infer the jump target at its worst. 5.1 Definition A signedness-agnostic interval with congruence classes (cc-interval) is the partially reduced product of a signedness-agnostic interval and a set of congruence classes, which share a common modulus. The residues of the congruence classes are all elements of a second interval. Thus, a cc-interval is given by two intervals and the modulus of the congruence classes, written ( a, b )(( c, d )[m]), where ( a, b ) denotes the range of the ccinterval, ( c, d ) denotes an interval containing the residues of the congruence classes, and m denotes the modulus of the congruence classes. Note that only the intersection with 31

40 5 Signedness-Agnostic Intervals with Congruences ( 0, m 1 ) of ( c, d ) is relevant, the rest is ignored. If no information about congruence classes is known, or the interval of residues would be equivalent to, the congruence information is omitted and a cc-interval is denoted equivalently to a normal signednessagnostic interval. However, some operations involving such cc-intervals can produce a more accurate result if they are able to restrict the result by inferring congruence classes. Thus, an element e is part of a cc-interval if and only if: true false e s = e ( a, b ) e a (e % m) b if s = if s = if s = ( a, b ) if s = a(b[m]) The domain of cc-intervals is not closed under complement. However, it is the partially reduced product of two domains closed under complement. As mentioned in Section 3.1, the domain of signedness-agnostic intervals is closed under complement. It is also possible to define a complement for a complement class, as we use an interval of allowed remainders to describe the congruence information of a cc-interval. Inverting this interval yields the complement. However, the complement of an interval a(b[m]) contains every number in a or b[m] and it is not possible to express this disjunction in every case. 5.2 Intervals revisited Often operations on cc-intervals need to join multiple intervals into another interval, but do not care about how many elements are included between some number m and 1 w. This is normally the case for the interval of allowed remainders, as elements between m and 1 w are by construction impossible remainders. Including these elements in the interval gives the ability to express a set of remainders r with the property x r x b x a. However, the operator given by Gange et al. produces the smallest interval, while we do not care about some parts of the interval. Thus, we define a small variation mod,m, which computes the smallest interval with respect to # mod,m, i.e., after intersecting the result with ( 0, m 1 ) and summing the sizes of the parts. # mod,m and bigger mod,m are thus simply defined as: 32

41 5.2 Intervals revisited # mod,m s = {#t t s ( 0, m 1 )} { t if #mod,m t > # mod,m s bigger mod,m (s, t) = s otherwise Next, we define the corresponding mod,m operator. Given two intervals, it first computes the join of both intervals. It then inverts it, yielding the larger gap between the two input intervals. As this gap is directly adjacent to s as well as t, we can just use the operator to merge it with s and t. Finally, we check which of the possible two intervals is smaller with respect to # mod,m and return that one. v s mod,m t = s t if # mod,m v # mod,m u where u = s t v = {u, s, t} otherwise Now, we are able to define mod,m. As one can see in Figure 5.2, it is a slight variation of, as we use mod,m instead of and bigger mod,m instead of bigger. mod,m s : s = sort(s) f = g = for e s do if e = (e = ( a, b ) b < a) then f = f mod,m e for e s do g = bigger mod,m (g, gap(f, e)) f = f mod,m e return bigger mod,m (g, f) Figure 5.2: Join operator for sets modulo m. Similar to mod,m, we define an operator range,r in Figure 5.3, which computes a upper bound of a set of intervals inside another interval r. Elements outside of r are not included in the result, even if the set of input intervals contains them. 33

42 5 Signedness-Agnostic Intervals with Congruences We first collect all subintervals of the input which lie in r. To simplify things later on, we split the input at the south pole. If no interval overlaps with r, the result is. Otherwise, we collect all possible upper and lower bounds. Now we have to distinguish two cases: If r contains the south pole, and thus a > b, there are two areas where intervals accumulate. One half of the input will be in the interval ( 0, b ) while the other lies in ( a, 2 w 1 ). If we find at least one input interval in both of them, we span our result from max(high) as the lower bound to min(low) as the upper bound, including the south pole. If one of these sets is empty, the result does not have to include the south pole. Thus, we can proceed as if r itself would not include the south pole and compute the minimum lower bound and the maximum upper bound of all input intervals. range,r s : if r = then return s if r = then return ( a, b ) = r t = {(c, d) x s, y < ssplit(x), ( c, d ) r y} if t = then return low = {c (c, d) t, ( c, d ) ( 0, b )} high = {d (c, d) t, ( c, d ) ( a, 2 w 1 )} if a b low = high = then else return ( min{c (c, d) t}, max{d (c, d) t} ) return ( max(high), min(low) ) Figure 5.3: Join operator for sets in a given range. We also define an utility operator % cc, which computes a set of possible remainders from an interval of residues: s % cc m = mod,m rem n(s, m) Additionally, we need two functions giving the largest element in an interval smaller or equal than some number, as well as the smallest element greater or equal. Such an 34

43 5.3 Structure element does not always exist, thus, we return if this is the case. Both functions are defined as: e next (e, t) = b if e t if t = ( a, b ) e > b otherwise e next (e, t) = a if e t if t = ( a, b ) e < a otherwise 5.3 Structure To define an inclusion operator, we have to consider the different possible cases which can occur. If both arguments lack congruence information, we can simply use the inclusion operator of signedness-agnostic intervals. However, if the assumed larger cc-interval t contains congruence information, we have to make sure that all possible remainders of the assumed smaller cc-interval s modulo the modulus of t are included in the interval of allowed remainders of t, using the rem n function defined in Chapter 3. If s contains congruence information, but t does not, we first check if the range of possible values of s is already included in t. If not, we check if any element in s range that is not an element of t is an element of s. Therefore, we intersect s range with the inverse of t and compute the set of possible remainders for each element of the intersection. If any of these remainders is an element of s range of allowed remainders, s is not a subset of t, otherwise it is one. In the last two cases we consider two cc-intervals with available congruence information. If the modulus of t divides the modulus of s, we check if all possible remainders of s are possible remainders of t, modulo t s modulus. Otherwise, we give a rough approximation in the last case: We strip all congruence information from s and check whether it is already a subset of t. While this is safe in the aspect that we never falsely declare something a subset of something else, we can loose precision in some corner cases. An example is given in Figure 5.5. However, we were not able to find a rule covering these corner cases and thus decided to accept the loss of precision for the moment. The operator is defined in Figure 5.4. The join of two cc-intervals is in some cases a lot more precise than the join of two signedness-agnostic intervals. For example, two singleton-intervals (containing only one element) can be efficiently merged into a cc-interval including a range from one number to the second and excluding all intermediate numbers using generated congruence information. Similary, we can join two intervals without congruence information, including the smaller gap between them in the range information and the larger gap in the congruence information. We then choose the maximal possible number as modulus, thus creating an intersection between these two intervals. However, if 1 w is an element of either inputs, it has to be an element of the result, thus 0 has to be part of the interval of allowed remainders. We could have also chosen 10 w as the modulus in this case, 35

44 5 Signedness-Agnostic Intervals with Congruences true if s = t = false if s = t = ( a, b ) ( c, d ) if s = ( a, b ) t = ( c, d ) ( a, b ) ( c, d ) if s = ( a, b ) t = ( c, d )(r[m]) i rem n (( a, b ), m) : i r true if s = a(b[m]) t = ( c, d ) s t = a ( c, d ) i a ( c, d ) if s = a(b[m]) t = ( c, d ) j num w (i, m) : j b = r b ( 0, m 1 1 ) if s = a(b[m 1 ]) t = c(d[m 2 ]) x rem n (r, m 2 ) : x d a c m 1 % m 2 = 0 a t if s = a(b[m 1 ]) Figure 5.4: Inclusion of cc-intervals. Figure 5.5: The red cc-interval ( 0, 50 )(( 0, 0 )[25]) is a subinterval of the blue cc-interval ( 54, 50 )(( 0, 9 )[16]), but our operator does not detect this. but keeping the modulus the same bit-width as every other number does simplify the implementation and design of all other operations, thus we decided against 10 w. If one or both cc-intervals contain congruence information, we compute a possible approximation of the result and then use the inf ercc helper function to compute the final result. We define the join operator in Figure 5.7. The infercc function gets two normal signedness-agnostic intervals s 1, s 2 and a ccinterval t as input. If the cc-interval carries no congruence information, it tries to infer congruence information from s 1 and s 2 and adds that then to t. Otherwise it computes a cc-interval, which contains at least all numbers in (s 1 s 2 ) t. It is defined in Figure

45 5.3 Structure Figure 5.6: Computing an upper bound for ( 5, 15 ) and ( 20, 30 ) yields a cc-interval with congruence information. By exploiting the congruence information, ( 5, 30 )(( 20, 15 )[63]) contains exactly the elements of ( 5, 15 ) and ( 20, 30 ). t c( {( a, b ), ( c, d ), c, z}[1 w ]) if s = ( a, b ) t = ( c, d ) where c = ( a, b ) ( c, d ) s t = { {0} if 1 w s 1 w t z = otherwise s t s ( a, a ) ( b, b )(( n, n )[c]) b ( n, n )(c ( n, n )[c]) ( a, b ) ( c, d ) infercc(a, ( c, d ), x) if s t if t s if s = ( a, b ) t = c(d[m]) if s = ( a, a ) t = ( b, b ) where c = max(a, b) w min(a, b) n = rem n (a, c) if t = ( a, a ) s = b(c[d]) where n = rem n (a, d) if s = ( a, b ) t = ( c, d ) if s = a(b[m]) t = ( c, d ) where r = {b} rem n (( c, d ), m) x = (a ( c, d ))( mod,mr[m]) infercc(a, c, x) if s = a(b[m 1 ]) t = c(d[m 2 ]) where m = gcd(m 1, m 2 ) r = rem n (b, m) rem n (d, m) x = (a c)( mod,mr[m]) Figure 5.7: Least upper bound of two cc-intervals. In a similar way we can take care of a meet-operator for cc-intervals. Clearly, if no congruence information is present, we just meet the intervals. Similary, if one cc-interval 37

46 5 Signedness-Agnostic Intervals with Congruences s 1 s 2 if t = t if t = t = a(b[m]) s 1 s 2 = if s 1 = s 2 = (s ( a, b ))(r[1 w ]) if t = ( a, b ) infercc(s 1, s 2, t) = where s = s 1 s { 2 {0} if 1 w s 1 w t z = otherwise r = {s 1, s 2, s, z} (s 1 s 2 ) ( a, b ) if t = ( a, b ) Figure 5.8: The inf ercc function. contains congruence information, we meet their ranges and are done. Otherwise, we need to make sure that the least common multiple of their moduli does not wrap around. We then extract the relevant information from each interval of remainders and intersect them. If the new modulus overflows, we know that only those numbers in both sets of s if s = t = t if t = s = ( a, b ) ( c, d ) if s = ( a, b ) t = ( c, d ) (( a, b ) c)(d[m]) if s = ( a, b ) t = c(d[m]) (( a, b ) c)(d[m]) if t = ( a, b ) s = c(d[m]) (a c)( mod,m r[m]) if s = a(b[m 1]) t = c(d[m 2 ]) m < 2 w s t = where m = lcm(m 1, m 2 ) r 1 = b ( 0, m 1 1 ) r 2 = d ( 0, m 2 1 ) r = {x y x r 1, y r 2 } a c r if s = a(b[m 1 ]) t = c(d[m 2 ]) where r 1 = b ( 0, m 1 1 ) r 2 = d ( 0, m 2 1 ) r = {x y x r 1, y r 2 } Figure 5.9: Greatest lower bound of two cc-intervals. 38

47 5.4 Self-feedback remainders and allowed values are possible values, and thus compute the meet of these three sets. A definition is given in Figure Self-feedback Operations on cc-intervals often compute interval and congruence information separately without performing any feedback between the computed information. However, it is often useful to assume certain properties for the interval as well as the congruence information. For example, the bounds of the interval should both be elements of the cc-interval. Otherwise, it would be possible to shrink the interval without changing the semantics, thereby potentially increasing the precision of a later operation. For brevity, we assume every cc-interval s(t[m]), constructed by some operation, is implicitly constrained by the following function: if shrink mod (t, m) = s if shrink mod (t, m) = ( 0, m 1 ) shrink(s, t, m) = shrink (s, t, m) otherwise where t = shrink mod (t, m) The first point we concern ourselves with is reducing the number of possible remainders. Therefore we use shrink mod, defined further below. Thus, if no remainder is possible after reducing them, no number in total is possible and we return. This handles a range of cases such as t = or m = 1 0 / t. In the next case, we discard congruence information which do not improve precision as every possible remainder is allowed. Again, we implicitly handle cases like t = or m = 1 0 t here, too. Otherwise we continue in shrink after reducing our set of possible remainders. shrink (s, t, m) = shrink (s, t, m) if shrink range (s, t, m) = otherwise where s = shrink range (s, t, m) If shrink range determines that no value is actually possible, we reduce the complete cc-interval to. Otherwise, we continue in shrink with the reduced range. 39

48 5 Signedness-Agnostic Intervals with Congruences x shrink(s, t, m) shrink (s, t, m) = shrink (s, t, m, r) s(t[m]) if s ( 0, m 1 ) s t = if s ( 0, m 1 ) s t = {x} if t t where t = shrink mod (s, t, m) if x r : x t where r = rem n (s, m) otherwise If the range of possible values is a subinterval of the range of possible remainders, we check whether their intersection is empty. If yes, the result is again. If they intersect only in one interval, we again have a result. Otherwise, we use the constrains from the set of possible values to try to reduce the interval of possible remainders further. If this produces a different result, we start the iteration again in shrink with the reduced values. While this clearly could form a loop, it would be decreasing t at each iteration and thus eventually terminate. Still, it could be the case that it takes a large number of iterations until it stabilizes. However, this can not happen, as t reduced by s can not shrink s again, otherwise shrink mod would have removed values from t which are a possible remainder for values in s. If we fail to reduce t, we check whether all possible remainders of s are included in t. If yes, we can continue in shrink, otherwise we are done. s if range,tr = ( a, b ) t = ( c, d ) shrink c = a % m (s, t, m, r) = d = (b a + (a % m)) % m s(t[m]) otherwise In this last step, we perform a check whether the congruence information adds anything not already included in s. Therefore we join all possible remainders and see if we can compute the same information as t. If this is the case, t is redundant and we discard it. Otherwise we are done and have a valid cc-interval with congruence information. To reduce the set of possible remainders, we first intersect the t with the interval of interesting remainders. We then compute the interval with the smallest number of elements between 0 and m 1 by using mod,m. shrink mod (t, m) = (t ( 0, m 1 )) mod,m 40

49 5.4 Self-feedback Similary, to exclude remainders with no value in the interval of possible values, which could yield it, we compute the set of possible remainders for the range of possible values and intersect them with the interval of allowed remainders. We then use range,t to compute a join with as few as possible elements in the intersection with t. shrink mod(s, t, m) = range,t {r t r remn (s, m)} To shrink the range of possible values, we first define two functions to find a maximum and a minimum bound starting from a given position. As we require that this bound modulo m should also be an element of t, it is possible that no such bound exists. We return to indicate this failure. pos if pos % m t r if u where u = next (pos % m, t) r = pos (pos % m) + u find max (pos, t, m) = r if u r < 2 w r 0 where u = next (pos % m + m, t) r = pos (pos % m) + u m otherwise pos if pos % m t r if u r < 2 w where u = next (pos % m, t) find min (pos, t, m) = r = pos (pos % m) + u r if t r < 2 w where r = pos (pos % m) + min(t) + m otherwise If the given position is already an upper bound, we are done. Otherwise, we try the next two possible candidates lower than pos. The first is obtained by first determining pos % m and then finding the first element in t less or equal than this. Using this, we can compute the next smaller number than pos divisible by m and add it. The second candidate is similar, but we additionally lower the bound by m. Thus, we have to be careful to still compute a representable number. If all this fails, no bound exists and we return. Similar to find max, find min yields the next lower bound greater than a given number. 41

50 5 Signedness-Agnostic Intervals with Congruences We can now define shrink range, where we try to reduce the set of possible values by excluding those where the congruence information makes them impossible. Clearly, if t is, no number is possible If t allows every number, we will not be able to shrink anything. However, if s is, but we can find a maximum bound, we are able to shrink s to a smaller set. If s spans the south pole, we split at the south pole, shrink both pieces and join the result. If s does not cross the south pole, we take the lower and upper bounds, reduce both and, if they do not cross each other, have a result. Otherwise no number is possible and our result is : r shrink range (s, t, m) = s ( min(t), u ) ( u, v ) if t = if t = if s = u where u = find max (2 w 1, t, m) if s = ( a, b ) b < a where r = {shrink range (x, t, m) x ssplit(s)} if s = ( a, b ) u v u < v where u = find min (a, t, m) v = find max (b, t, m) otherwise 5.5 Operations As already mentioned, one has to be careful with numbers wrapping around during operations. Thus, to define addition we first define a predicate to determine whether the addition of two intervals can result in a wrap-around: wrap-around(s, t) = s t (max(s) + max(t) 2 w ) Clearly both intervals have to be different from. Additionally, adding the maxima of the intervals has to result in at least 2 w, otherwise no wrap-around can happen. If numbers wrap around, we need to correct our congruence information. Therefore we define add cc, which, given an interval of possible remainders and a modulus, extends the interval of remainders by those possible via wrap-around. The possible new remainders for some set of remainders t are t, t + (m 2 w % m), and t (2 w % m): 42

51 5.5 Operations add cc (t, m) = {a, b, c} mod,m where o = 2 w % m a = t % cc m b = (t + ( m o, m o )) % cc m c = (t ( o, o )) % cc m Now we can define our addition operator. If both arguments carry congruence information, the new range of remainders is the sum of the old range of remainders, and the new modulus is the greatest common divisor of both moduli, similar to the addition of two congruence classes. We then check if wrap-around is possible, and if it is, we use add cc to include the additional remainders. Otherwise, we use % cc to narrow the range of relevant remainders to 0 to m 1. If only one summand contains congruence information, we can assume as the modulus of the other summand. The range of possible values thus also is the range of possible remainders, and we proceed similar as if both summands had congruence information. The only difference is that we assume gcd(m, ) = m holds (we can choose an arbitrary number larger than 2 w 1 as a possible second modulus). If no summand has available congruence information, addition is performed as with signedness-agnostic intervals, thus we denote this with + i. (a + c)(add cc (b + d, m)[m]) if s = a(b[m 1 ]) t = c(d[m 2 ]) wrap-around(a, c) where m = gcd(m 1, m 2 ) (a + c)(((b + d) % cc m)[m]) if s = a(b[m 1 ]) t = c(d[m 2 ]) where m = gcd(m 1, m 2 ) (a + ( c, d ))(add cc ((b + ( c, d )), m)[m]) if s = a(b[m]) t = ( c, d ) s + t = wrap-around(a, ( c, d )) (a + ( c, d ))(((b + ( c, d )) % cc m)[m]) if s = a(b[m]) t = ( c, d ) (a + ( c, d ))(add cc ((b + ( c, d )), m)[m]) if t = a(b[m]) s = ( c, d ) wrap-around(a, ( c, d )) (a + ( c, d ))(((b + ( c, d )) % cc m)[m]) if t = a(b[m]) s = ( c, d ) s + i t otherwise We can define subtraction as a b = a + ( b). Thus, we need to define negation next. If we have congruence information available, we have to distinguish whether 0 is a valid remainder or not. If 0 is one, we have to add 2 w % m as an allowed remainder. For 43

52 5 Signedness-Agnostic Intervals with Congruences example, consider 8 3 = 253. While 3 clearly is divisible by 3, 253 is not but has the remainder 1. So we have to include 256 % 3 = 1 as a possible remainder. Similary to addition, if no congruence information is present, we resort to negation as defined for signedness-agnostic intervals, denoted i : ( a)(( mod,m d)[m]) if s = a(b[m]) 0 b where c = ( 2 w % m, 2 w % m ) s = d = (( b) % w m) {c} ( a)((( b) % cc m)[m]) if s = a(b[m]) i s otherwise The multiplication of two cc-intervals leads to three interesting cases. In the first case one operand is a constant. We handle this case with the mul helper function. In the second case we have the multiplication of two operands with congruence information. However, the possible remainder for each operand is just a single number. Additionally, we also require that wrap-around can not occur. In this case, we can perform multiplication with a combination of interval multiplication and multiplication of two congruence classes, as in Chapter 4. The last case consists of no useable information, and we just perform a multiplication of the allowed ranges, denoted by i, and throw away all congruence information. ( a w b, a w b ) if s = ( a, a ) t = ( b, b ) mul(a, t) if s = ( a, a ) mul(b, s) if t = ( b, b ) s t = (a b)(( c 1 w c 2, c 1 w c 2 )[m]) if s = a(( c 1, c 1 )[m 1 ]) t = b(( c 2, c 2 )[m 2 ]) max(a) max(b) < 2 w where m = gcd(c 1 m 2, m 1 c 2, m 1 m 2 ) s i t otherwise Multiplication of a cc-interval with a constant u again yields multiple cases. Beside the obvious first three cases, the multiplication of with a constant yields a cc-interval which each element congruent to the greatest common divisor of 2 w and u. Naturally, this yields a modulus of the form 2 x, i.e., all factors of 2 if one would factorize u. Next, if no congruence information is present and even the maximum of t is to small to wrap around after multiplication with u, we know that the result will always will be divisible by u. The next case is similar to t =, but this time t just spans an interval with a large enough maximum such that a wrap-around is possible. Otherwise, if t carries congruence information, we handle the case with mul mod. 44

53 5.5 Operations if t = ( 0, 0 ) if u = 0 t if u = 1 (( 0, 0 )[gcd(u, 2 w )]) if t = r(( 0, 0 )[u]) if t = ( a, b ) (max(t) u) < 2 w mul(u, t) = where r = ( u, u ) ( a, b ) r(( 0, 0 )[gcd(u, 2 w )]) if t = ( a, b ) where r = ( u, u ) ( a, b ) mul mod (u, a, b, m, r) if t = a(b[m]) where r = (( u, u ) a) (( u, u ) b) In mul mod we consider four cases. In the first case we have neither wrap-around for possible values nor for the new modulus. Thus, we can safely multiply everything by u. In the second case, wrap-around is not possible, but the new modulus would be a multiple of 2 w. However, as the elements of the interval itself are small enough, we can ignore this and use u as a new modulus. Then the only possible remainder is 0. r denotes the possible range for the result in this case and is passed from mul. As m w u is at least 2 w, we know that the range of possible remainders times u spans at least the range of the range of possible numbers times u, and the result has to lie in both intervals. The next case is similar, but either the new modulus or the new range would allow wrap-around, so any congruence information we infer would be incorrect. Thus, the range of possible values is the same as in the second case, but no congruence information is available. In the last case have to deal with wrap-around in the range of possible values as well as a new modulus, which is not a multiple of 2 w. Thus, we have to account for that and compute the greatest common divisor of the new modulus and 2 w. Finally, mul mod is then defined as: 45

54 5 Signedness-Agnostic Intervals with Congruences x(y[m u]) r(( 0, 0 )[u]) mul mod (u, a, b, m, r) = r x(y[n]) if max(a) u < 2 w m u < 2 w where x = ( u, u ) a y = ( u, u ) b if max(a) u < 2 w m w u = 0 if max(a) u < 2 w gcd(u m, 2 w ) = 2 w otherwise where n = gcd(u m, 2 w ) x = ( u, u ) a y = (( u, u ) b) % cc n Division and remainder operations are not really well supported by our analysis. Instead, we default to the operations provided by the signedness-agnostic interval analysis, discarding any computed congruence information. However, in some cases we can use our congruence information if we have to compute an unsigned remainder: if t = ( 0, 0 ) {c d c remn (a, u), if t = ( u, u ) s = a(b[m]) d (rem n (b, u)} m % u = 0 s % u t = (a % u ( u, u ))((a % cc u)[u]) if t = ( u, u ) (s = a(b[m]) (s = a = )) s % ui t otherwise If t only contains the number 0, no number is possible. Otherwise, if u divides the modulus m of s, we can compute a set of possible remainders. Here each remainder lies both in a % u u and b % u u, so we compute the exact sets for them and take the intersection of all combinations. Finally we join everything. In the third case, we just compute the set of possible results and the set of possible remainders. Otherwise, if t has not exactly one element, we default to the % u operator of signedness-agnostic intervals, denoted % ui here, and discard any congruence information. Most relational operators do not benefit from congruence information. Only when checking for equality of two cc-intervals cases like ( 5, 15 )(( 0, 0 )[10]) = ( 7, 17 )(( 2, 2 )[5]) could arise. In such a case, we know that no two numbers can never be equal, although their ranges overlap. To check such cases, we compute the greatest common divisor of both 46

55 5.6 Widening moduli, and, if it is different from 1, for each interval of remainders their set of remainders with this new modulus. If the intersection of all these sets is empty, equality is impossible. Otherwise, we default to the predicate for signedness-agnostic intervals, denoted eq i. {false} if s = a(b[m 1 ]) t = c(d[m 2 ]) m > 1 {x y x rem n (b, m), eq(s, t) = y rem n (d, m)} = where m = gcd(m 1, m 2 ) eq i (s, t) otherwise 5.6 Widening To ensure fast convergence, we again need to use a widening operator. If no congruence information is present, we perform widening as one would perform it for plain signedness-agnostic intervals, denoted by i. If only one operand carries congruence information, we widen the range of possible values of the first operand with those of the second. Additionally, we compute an interval of possible remainders for the operand without congruence information using the % cc operator. We then can widen the congruence information, too, without immediatly discarding it. However, if we have to widen repeatedly, it will eventually contain all numbers between 0 and m 1 and be discarded. If both operands contain congruence information, we distinguish two cases. If the interval of both operands is a singleton interval, we try to preserve it. Therefore, we join both intervals. If they were equal, the result will still be the same interval. If not, the result will be an interval from one remainder to the other. In that case, the first case is not possible in later iterations. Thus, we either stay in the first case on every iteration and thus the result stabilizes if the range of possible values stabilizes, or another case applies eventually, thus increasing the set of remainders until it stabilizes. In the case that the intervals of possible remainders are not singleton intervals, we use the widening operator for intervals to ensure fast convergence for the congruence information. If both operands contain congruence information, the modulus of the new cc-intervals is the greatest common divisor of the moduli of both operands, similar to the operator. Following this, we need to apply the % cc operator to the remainder intervals to ensure that widening these intervals also widens the sets of possible remainders. Thus, our widening operator for cc-intervals is defined as: 47

56 5 Signedness-Agnostic Intervals with Congruences (s 1 s 2 )(r[m]) if s = s 1 (( t 1, t 1 )[m 1 ]) t = s 2 (( t 2, t 2 )[m 2 ]) where m = gcd(m 1, m 2 ) r = (( t 1, t 1 ) ( t 2, t 2 )) % cc m (s 1 s 2 )(r[m]) if s = s 1 (t 1 [m 1 ]) t = s 2 (t 2 [m 2 ]) where m = gcd(m 1, m 2 ) s t = r = (t 1 t 2 ) % cc m (s 1 ( a, b ))(r[m 1 ]) if s = s 1 (t 1 [m 1 ]) t = ( a, b ) where r = t 1 (( a, b ) % cc m 1 ) (( a, b ) s 2 )(r[m 2 ]) if s = ( a, b ) t = s 1 (t 1 [m 1 ]) s i t where r = (( a, b ) % cc m 2 ) t 2 otherwise Similary to signedness-agnostic intervals, we perform widening after every iteration if the analysis did not converge after a small number of iterations. 48

57 6 Implementation in Jakstab We implemented signedness-agnostic intervals as well as our new cc-intervals in the binary analysis tool Jakstab [13]. Jakstab translates disassembled assembly code into a sequence of simple instructions [3], emulating the behavior of the original instruction. These instructions are then fed to the analyses selected by the user of the tool. An analysis only has to work with the simplified language, which basically consists of variable and memory assignments, assumptions known to be true after a branch, and the allocation and deallocation of variables (the stack pointer, for example, is just a plain variable from the perspective of an analysis). Any control flow is handled by Jakstab itself and is not a concern of our analysis. Still, we had to work around some shortcomings in the design of Jakstab and the Java programming language, in which Jakstab is written. While Jakstab provides abstractions for the analyzed assembly code, the interface to evaluate expressions provided by it only covers addition, negation, multiplication, and casting a value to a different bit-width. Shifts, division, remainder, and bitwise logic operations are not exposed by the interface. Thus, we had to write our own evaluator to handle other operations. Similarly, while Jakstab contains utility classes to track the valuations of variables or memory locations, we had to derive our own class managing these these regions. While the Jakstab framework provides such a class, it uses the previously mentioned interface and thus only exposes a fraction of the relevant operations for our purposes. A third problem was proper handling of variable bit-width arithmetic and the absence of unsigned integer types in the Java programming language itself. As most of our analysis has to deal with fixed-precision integer arithmetic with a specific bit-width, one of the first things we did was to design a class abstracting the different operations. Here, special care had to be taken, as it had to support all bit-widths between 1 and 64 bits, as Jakstab in some situations creates expressions with unusual bit-widths, such as 5 bit. Additionally, because of Java s lack of unsigned integral types, some operations like unsigned division are just not provided by Java and had to be emulated by distinguishing the different possible cases and, if necessary, falling back to arithmetic using Java s builtin infinite-precision integer type. Although Jakstab provides an abstraction for variable bit-width integers, we found it lacking many required operations. For example, it did neither provide a function to compute the greatest common divisor nor a logarithm to base 2. Also, it did handle arithmetic operations by first constructing an expression object for the desired operation and then trying to evaluate the expression. Thus, to simplify things, we implemented our own class. An important part of the implementation was ensuring that the worklist algorithm used internally by Jakstab reaches a fixed point in an acceptable amount of time. As intervals as well as cc-intervals contain infinite ascending chains, or at least chains of length 2 64 due to the fixed-precision arithmetic underlying all operations, one has to use widening to accelerate convergence to a fixed point. Another consideration in this part is the fact 49

58 6 Implementation in Jakstab that the operator for cc-intervals in rare cases does not determine that one cc-interval contains all elements of another one, as discussed earlier. However, it is safe to err on this side, as it just means that we loose some precision and have to iterate a further time, joining both cc-intervals into a superset of both. While it would certainly be an optimization to better handle this case, the effect of it is bounded and does not affect the feasibility of performing an analysis using cc-intervals. The final size of our implementation measures a bit more than 5000 lines of code, with whitespace and comments removed. Out of these 5000 lines, around 1500 lines each contribute to the signedness-agnostic interval analysis as well as our interval analysis with congruence classes. The remaining code consists of utility classes to correctly track the valuation of variables and memory locations as well as two drivers for each kind of interval analysis. 50

59 7 Evaluation To evaluate the usefulness of our new approach, we use our implementation in the Jakstab binary analysis tool and compare the effectiveness of our implementation with three other analyses. The first analysis we compare against is a strided interval analysis (SI). It was implemented by Jakstab s author Johannes Kinder. We use it to compare the approach of signedness-agnostic intervals with traditional intervals, which assume that the left bound of an interval has to be smaller than the right bound. The second analysis is our implementation of signedness-agnostic intervals without congruence information (SAI). Clearly, if we can get a more precise result with congruence information than without, the effort paid off. The last analysis we compare against is Bddstab, an analysis tracking sets of addresses using binary decision diagrams [15] (BDD). With it we can compare the general approach of computing intervals against other analysis approaches. We measured the time it took to analyze a program, the number of recovered instructions, whether the analysis computed a sound result, the number of indirect branches in the reconstructed control flow (IB), and the number of unresolved branches after the analysis (UB). Measuring the execution time gives an idea about how much effort an analysis takes compared to the results it provides. While the number of instructions gives a rough idea about how much of the program was recovered, in some cases, an analysis also recovers unreachable instructions. Unreachable instructions are, however, not interesting, so we also examined the recovered assembly code from each analysis. The count of indirect branches gives an idea about how complex the analyzed program was. Note that we do not consider branches of the form jump mem[constant] to be indirect branches if constant points into constant memory. Finally, the number of unresolved branches corresponds to the number of branch instructions where an indirect branch could be taken, but the target could not be resolved by the analysis. Thus, a conditional indirect branch to an unknown location is only an unresolved branch if the analysis infers that the branch could be executed. A conditional branch to an unknown location, for which the analysis infers the condition never holds, does not count as an unresolved branch. If an analysis can not resolve a branch, Jakstab assumes execution halts at this point and marks an analysis as unsound. 7.1 Results The first program we analyzed was a program printing three strings to the terminal. The first two strings are printed in a loop, the last one in a subroutine. It was written in assembly language, so it does not need any code initializing some kind of runtime environment. While all four analyses performed equally well and reconstructed the same 51

60 7 Evaluation parts of the control flow, all also failed to resolve the same indirect jump. To print three strings, the program requests three times a handle to print on using the GetStdHandle library function. However, the third time this happens in a subroutine. Thus, the stack also holds the return address of the subroutine, which confuses all analyses. Program Analysis Time (ms) Instructions Sound IB UB helloworld SI No 1 1 helloworld SAI No 1 1 helloworld SAI-CC No 1 1 helloworld BDD No 1 1 Table 7.1: Results for the helloworld program. As one can see in Table 7.1, both of the analyses we implemented take a large amount of time. This is caused by a large number of iterations until the analyses stabilize. As other test programs show completely different behavior, the most likely cause is some sort of bug in our implementation. The second analyzed program was a simple program printing a string, written in C. Thus, an analysis first has to work through the startup-code of the C-runtime. This time, the analyses performed quite different, with the strided interval analysis recovering the most instructions. Bddstab could also recover a lot of code. An interesting fact is that neither did recover a superset of code than the other. However, neither did one analysis recover uninteresting code, i.e., code which in fact is not code but data or just a long string of zeros. The signedness-agnostic interval analysis could resolve the fewest branches and was stuck at a seemingly simple subroutine. Similary, our new analysis could also not resolve the same subroutine, but did resolve a second indirect branch the signedness-agnostic intervals could also not resolve. Further investigation may be needed for this example, to understand what exactly is causing this trouble for both analyses, where Bddstab and the strided interval analyses do not have problems with resolving this branch. Program Analysis Time (ms) Instructions Sound IB UB helloc SI No 3 11 helloc SAI No 1 2 helloc SAI-CC No 1 1 helloc BDD No 3 5 Table 7.2: Results for the helloc program. This time, the execution times seen in Table 7.2 are much more reasonable. The strided interval analysis performs the best in this category, too, despite the fact that it did work through a lot more states than the other analyses. As one can also see, the additional congruence information carried by our new analysis has a moderate price of around 10% 52

61 7.1 Results to 20% slower execution time with respect to the recovered instructions. However, compared to the strided interval analysis, the signedness-agnostic interval analysis performs between 5 to 6 times slower. One explanation could be our use of a dedicated class to handle integer-arithmetic on k-bit integers, while the strided interval analysis is not implemented using such an abstraction. The third program allocates two pointers and clears the memory they point to. However, instead of using a classical allocation subroutine like, for example, malloc, a special assembler instruction is used. The instruction is recognized by Jakstab, which then assumes that the two pointers allocated by it point to different parts of memory, i.e., different memory regions. Program Analysis Time (ms) Instructions Sound IB UB regionprecision SI No 0 1 regionprecision SAI No 0 1 regionprecision SAI-CC No 0 1 regionprecision BDD No 0 1 Table 7.3: Results for the regionprecision program. Table 7.3 shows both Bddstab and our new analysis recover the same parts of the program. The signedness-agnostic interval analysis also recovers it, but additionally over-approximates some jumps, leading to some recovered instructions which are not part of the original program, but an interleaving of the bytes of other instructions. The strided interval analysis is not able to resolve the return statement of the subroutine allocating the two pointers and thus gets stuck quite early. However, none of the analyses are able to prove that the recovered program is the complete control flow graph, as they all fail to resolve one indirect branch. The next test programs are three micro-benchmarks. They were written by Johannes Kinder. All use uninitialized registers and pointer arithmetic to compute a few indirect jumps, but constrain the possible jump targets in such a way that no jump can lead to code outside of the benchmark. An analysis then has to propagate the sets of possible values through the different arithmetic operations performed to finally compute the branch targets. Program Analysis Time (ms) Instructions Sound IB UB demo1 SI No 1 1 demo1 SAI No 1 1 demo1 SAI-CC No 1 2 demo1 BDD Yes 1 0 Table 7.4: Results for the first micro-benchmark. 53

62 7 Evaluation Table 7.4 shows that only Bddstab was able to reconstruct the complete control flow graph. The strided interval analysis could not resolve the last jump to the exit point of the benchmark, while the signedness-agnostic interval based analyses computed an overapproximation, recovered data as code and then failed to resolve all indirect branches in this over-approximation. Clearly, it is harder to resolve indirect branches in such an over-approximation as it easily happens that the bytes are wrongly classified as code that jumps to a completely arbitrary address, i.e., to that in an uninitialized register. As in the first benchmark, the runtime of both analyses is much higher than those of the other two analyses. For the signedness-agnostic interval analyses, this is easily justified by the large number of false positives it disassembled and analyzed. For our new cc-interval analysis this can only be a part of the reason, as its execution time lies magnitudes above the expected runtime. This is caused most likely by the same reason as in the first analyzed program. Program Analysis Time (ms) Instructions Sound IB UB demo2 SI No 1 1 demo2 SAI No 1 1 demo2 SAI-CC Yes 2 0 demo2 BDD Yes 2 0 Table 7.5: Results for the second micro-benchmark. The second micro-benchmark in Table 7.5 divides the analyses in two sets: The first two interval analyses were not able to resolve the first indirect jump and thus terminated quite fast while our analysis as well as Bddstab were able to completely reconstruct the control flow graph. Program Analysis Time (ms) Instructions Sound IB UB demo3 SI No 1 1 demo3 SAI No 1 1 demo3 SAI-CC No 3 1 demo3 BDD No 3 1 Table 7.6: Results for the third micro-benchmark. The last micro-benchmark in Table 7.6 shows similar results. The first two interval analyses failed again to resolve the first jump while Bddstab and our analysis gave a much better result. They failed to resolve one last indirect branch, thus one edge in the reconstructed control flow graph is missing. However, every instruction of the original assembly code is included. As one can see in the results from the six analyzed programs, we could not only increase the general precision by combining signedness-agnostic intervals with congruence classes, but the increased precision is actually enough to resolve more indirect branches 54

63 7.1 Results than without congruence information. However, in certain cases the analysis iterates an inacceptable amount of time, so this needs further investigation. Most likely this corresponds to a fault in our implementation, for which we were not able to find the cause until today. Also, it would be of interest to find out why the strided interval analysis performed so much better in the helloc benchmark. Compared to Bddstab, our analysis is an orthogonal approach. In some situations, it leads to better results, in other situations the results are worse. While it is possible to run multiple analyses in parallel with the Jakstab framework, we did not evaluate this possibility, nor did we look into how computed knowledge from, for example, Bddstab could be used to increase the precision of our analysis, or vice-versa. 55

64

65 8 Related work Traditional interval analysis [17, 4] is clearly a basis to analyze low-level machine code [2]. It is, however, not sound for fixed-precision integer arithmetic, which is normally the only kind of integer arithmetic possible in low-level machine code. Gange et al. [7, 19] therefore adapted the domain to wrapped, signedness-agnostic intervals. We have taken their work further and extended it with congruence information [9]. Thus, we are able to perform sound analysis of low-level machine code and still exploit the advantages of strided intervals or congruence classes. The idea to increase precision by combining interval analysis with congruence information is not new. For example, Nakanishi et al. define a modulo interval [18], which combines an interval with a congruence class [9]. However, their analysis is designed for arbitrary-precision integers and thus not sound for fixed-precision integers, which one encounters during analysis of low-level machine code. Even if the analysis would be modified to be aware of wrap-around, the underlying classical interval domain loses all precision on wrap-around. This is caused by the fact that it assumes a smaller left than right bound and if this is no longer the case, defaults to. Similary, wrap-around often yields a new modulus of 1 for the congruence class. Our analysis can at least partially avoid such problems. Our addition operator extends the set of possible remainders instead of reducing the modulus, preserving precision partially. Another possibility to extend the precision of an interval domain could be a combination with bit-blasting [16]. Bit-blasting maps easily to the nature of fixed-precision integers and thus could need a lot less work than we need to handle wrap-around. On the other hand, non-linear arithmetic operations such as multiplication, division, and remainder are extremely complicated for a bit-blasting approach while our approach can rather easily deal with such operations. Our analysis can also partially mimic bit-blasting for the lower bits of a value, if the modulus corresponds to a power of 2. Of course the use of intervals of any kind scales much worse when tasked with representing bit patterns not adjacent to each other on the number circle. There exist a wide range of different analyses to compute possible branch targets. For example, the bounded address-tracking analysis [13] already implemented in Jakstab, or the address-tracking analysis Bddstab [15] implemented by Mattsen et al., are precisely designed to resolve these kinds of indirect branches. Our analysis is less focused on sets of addresses and concerns itself more with general valuations of program variables. Following this, it is less effective if a large set of possible addresses forms a possible valuation of a program variable. On the other hand, it has fewer problems with arithmetic. For example, Bddstab has very limited support for multiplication compared to our analysis. Thus, our analysis can more likely utilize knowledge it computes about nonpointer program variables, i.e., to detect impossible conditional branches. This can in 57

66 8 Related work turn help reducing the final control flow graph by pruning uninteresting, dead branches. For our use case of computing indirect branches, one could also decide to drop the requirement of a sound analysis. While a control flow graph reconstructed in such a way may be missing some edges, such an approach can also help to resolve otherwise unknown jump targets. For example, an analysis could decide to ignore any wrap-around, thus simplifying operations such as multiplication and addition. If one encounters something like ( a, b ) ( c, c ), an unsound result could be ( a w c, b w c )(( 0, 0 )[c]). While this only includes a subset of the possible values, it would be better than to compute a correct result, which can easily reach, and thus no information is available anymore. One can take a similar approach to disassemble executable code. For example, the GNU objdump [6] program performs a linear sweep [22] through an executable. While this is simple and often sufficient for many tasks, it is not sound and can easily get confused by data embedded in the executable code or objuscated machine code [14]. More sophisticated approaches are chosen by Ida Pro [11] or Radare [21], which perform a recursive traversal of reachable instructions and apply heuristics to identify entry points to subroutines. Compared to Jakstab, they make more assumptions about the execution environment of the analyzed code and, for example, do not handle selfmodifying code. Depending on the use case, a similar approach could be taken with our analysis. Ignoring wrap-around and just computing a subset of the possible values could, for example, be useful for finding bugs in software. If a bug is present in such an unsound analysis, it would also be present in a sound analysis, although both results could of course be false positives. However, an array index over-approximated to is not really useful. On the other hand, if a more precise, albeit unsound, index also exhibits the problem, it could certainly aid finding and fixing the problem. 58

67 9 Further work and conclusion We have shown that it is possible to combine signedness-agnostic intervals with congruence information in a sound way. Our implementation achieves a greater precision than signedness-agnostic intervals alone while still being not much more computationally expensive. This becomes clear from our evaluation results presented in Chapter 7. We will also submit our implementation to be integrated into the publicly available version of Jakstab for others to review and extend. In our description of our implementation, we have shown how to use congruence and interval information to strengthen each other. We have also shown how one can deal with wrap-around without completely losing precision. One aspect which remains open for future work is the operator for our domain. Right now, our implementation gives false negatives in some rare cases. While this does not affect the soundness or termination of the analysis, it decreases the precision and increases the number of iterations needed until a fixed point is found. It can, however, not lead to an unbounded number of iterations, as our least upper bound operator gives a result for which both arguments are considered smaller by our operator. Before submitting our code, we will also have to find the reason for the unreasonably large execution time of some of the benchmarks. In this work, we concentrated on the analysis of low-level machine code. Undoubtedly however, other areas of application exist for our analysis. For example, one could integrate the analysis into a compiler and evaluate its usefulness to program optimization. Software verification would be another possible use case of the analysis. 59

68

69 Bibliography Bibliography [1] G. Balakrishnan and T. Reps. WYSINWYX: What You See is Not What You execute. In: ACM Trans. Program. Lang. Syst (2010), 23:1 23:84. doi: / [2] Jörg Brauer, Andy King, and Stefan Kowalewski. Abstract Interpretation of Microcontroller Code: Intervals Meet Congruences. In: Science of Computer Programming 78.7 (2013), pp doi: /j.scico [3] C. Cifuentes and S. Sendall. Specifying the semantics of machine instructions. In: Program Comprehension, IWPC 98. Proceedings., 6th International Workshop on. 1998, pp doi: /WPC [4] P. Cousot and R. Cousot. Abstract interpretation: a unified lattice model for static analysis of programs by construction or approximation of fixpoints. In: Conference Record of the Fourth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages. ACM, 1977, pp doi: / [5] P. Cousot and R. Cousot. Comparing the Galois Connection and Widening/Narrowing Approaches to Abstract Interpretation. In: Proceedings of the International Workshop Programming Language Implementation and Logic Programming, PLILP 92, Springer-Verlag, 1992, pp doi: / _142. [6] Free Software Foundation. objdump. url: docs/binutils/objdump.html (visited on 05/24/2016). [7] G. Gange et al. Interval Analysis and Machine Arithmetic: Why Signedness Ignorance Is Bliss. In: ACM Trans. Program. Lang. Syst (2015), 1:1 1:35. doi: / [8] Graeme Gange et al. Abstract Interpretation over Non-lattice Abstract Domains. In: Springer-Verlag, 2013, pp doi: / _3. [9] P. Granger. Static analysis of arithmetical congruences. In: International Journal of Computer Mathematics (1989), pp doi: / [10] P. Granger. Static Analysis of Linear Congruence Equalities Among Variables of a Program. In: Proceedings of the International Joint Conference on Theory and Practice of Software Development on Colloquium on Trees in Algebra and Programming (CAAP 91): Vol 1. TAPSOFT 91. Springer-Verlag, 1991, pp doi: / _10. [11] IDAPro: The Interactive Disassemblyer. url: https : / / www. hex - rays. com / products/ida/ (visited on 05/24/2016). 61

70 Bibliography [12] Gary A. Kildall. A Unified Approach to Global Program Optimization. In: Proceedings of the 1st Annual ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages. POPL 73. ACM, 1973, pp doi: / [13] Johannes Kinder. Static Analysis of x86 Executables. PhD thesis. Darmstadt: Technische Universität, url: darmstadt.de/ 2338/. [14] Cullen Linn and Saumya Debray. Obfuscation of Executable Code to Improve Resistance to Static Disassembly. In: Proceedings of the 10th ACM Conference on Computer and Communications Security. CCS 03. ACM, 2003, pp doi: / [15] S. Mattsen, A. Wichmann, and S. Schupp. A non-convex abstract domain for the value analysis of binaries. In: 2015 IEEE 22nd International Conference on Software Analysis, Evolution, and Reengineering (SANER). 2015, pp doi: /SANER [16] Antoine Miné. Abstract Domains for Bit-Level Machine Integer and Floatingpoint Operations. In: ATx 12/WInG 12: Joint Proceedings of the Workshops on Automated Theory exploration and on Invariant Generation. Vol. 17. EPiC Series. 2012, pp [17] Ramon E. Moore, R. Baker Kearfott, and Michael J. Cloud. Introduction to Interval Analysis. Philadelphia, PA, USA: Society for Industrial and Applied Mathematics, isbn: , [18] T. Nakanishi et al. The modulo interval: a simple and practical representation for program analysis. In: Parallel Architectures and Compilation Techniques, Proceedings International Conference on. 1999, pp doi: / PACT [19] Jorge A. Navas et al. Signedness-agnostic program analysis: Precise integer bounds for low-level code. In: Springer-Verlag, doi: / _9. [20] Flemming Nielson, Hanne R. Nielson, and Chris Hankin. Principles of Program Analysis. Springer-Verlag, isbn: [21] Radare: a Portable Reversing Framework. url: (visited on 05/24/2016). [22] B. Schwarz, S. Debray, and G. Andrews. Disassembly of Executable Code Revisited. In: Proceedings of the Ninth Working Conference on Reverse Engineering (WCRE 02). WCRE 02. IEEE Computer Society, 2002, pp url: http: //dl.acm.org/citation.cfm?id= [23] Henry S. Warren. Hacker s Delight. 2nd. Addison-Wesley Professional, isbn: ,

Interval Analysis and Machine Arithmetic: Why Signedness Ignorance Is Bliss

Interval Analysis and Machine Arithmetic: Why Signedness Ignorance Is Bliss 1 Interval Analysis and Machine Arithmetic: Why Signedness Ignorance Is Bliss GRAEME GANGE, JORGE A. NAVAS, PETER SCHACHTE, HARALD SØNDERGAARD, and PETER J. STUCKEY, The University of Melbourne, Australia

More information

Change- and Precision-sensitive Widening for BDD-based Integer Sets

Change- and Precision-sensitive Widening for BDD-based Integer Sets Bachelor hesis elix Lublow Change- and Precision-sensitive Widening for BDD-based Integer Sets October 06, 2016 supervised by: Prof. Dr. Sibylle Schupp Sven Mattsen Hamburg University of echnology (UHH)

More information

Arithmetic Processing

Arithmetic Processing CS/EE 5830/6830 VLSI ARCHITECTURE Chapter 1 Basic Number Representations and Arithmetic Algorithms Arithmetic Processing AP = (operands, operation, results, conditions, singularities) Operands are: Set

More information

Lecture Notes on Ints

Lecture Notes on Ints Lecture Notes on Ints 15-122: Principles of Imperative Computation Frank Pfenning Lecture 2 August 26, 2010 1 Introduction Two fundamental types in almost any programming language are booleans and integers.

More information

Bits, Words, and Integers

Bits, Words, and Integers Computer Science 52 Bits, Words, and Integers Spring Semester, 2017 In this document, we look at how bits are organized into meaningful data. In particular, we will see the details of how integers are

More information

Chapter 2: Number Systems

Chapter 2: Number Systems Chapter 2: Number Systems Logic circuits are used to generate and transmit 1s and 0s to compute and convey information. This two-valued number system is called binary. As presented earlier, there are many

More information

Detection of Zeno Sets in Hybrid Systems to Validate Modelica Simulations

Detection of Zeno Sets in Hybrid Systems to Validate Modelica Simulations Bachelor Thesis Detection of Zeno Sets in Hybrid Systems to Validate Modelica Simulations Marcel Gehrke July 20, 2012 supervised by: Prof. Dr. Sibylle Schupp Technische Universität Hamburg-Harburg Institute

More information

SCHOOL OF ENGINEERING & BUILT ENVIRONMENT. Mathematics. Numbers & Number Systems

SCHOOL OF ENGINEERING & BUILT ENVIRONMENT. Mathematics. Numbers & Number Systems SCHOOL OF ENGINEERING & BUILT ENVIRONMENT Mathematics Numbers & Number Systems Introduction Numbers and Their Properties Multiples and Factors The Division Algorithm Prime and Composite Numbers Prime Factors

More information

Multiplication of BDD-Based Integer Sets for Abstract Interpretation of Executables

Multiplication of BDD-Based Integer Sets for Abstract Interpretation of Executables Bachelor hesis Johannes Müller Multiplication of BDD-Based Integer Sets for Abstract Interpretation of Executables March 19, 2017 supervised by: Prof. Dr. Sibylle Schupp Sven Mattsen Hamburg University

More information

Excerpt from "Art of Problem Solving Volume 1: the Basics" 2014 AoPS Inc.

Excerpt from Art of Problem Solving Volume 1: the Basics 2014 AoPS Inc. Chapter 5 Using the Integers In spite of their being a rather restricted class of numbers, the integers have a lot of interesting properties and uses. Math which involves the properties of integers is

More information

The PAW Architecture Reference Manual

The PAW Architecture Reference Manual The PAW Architecture Reference Manual by Hansen Zhang For COS375/ELE375 Princeton University Last Update: 20 September 2015! 1. Introduction The PAW architecture is a simple architecture designed to be

More information

Chapter 4. Operations on Data

Chapter 4. Operations on Data Chapter 4 Operations on Data 1 OBJECTIVES After reading this chapter, the reader should be able to: List the three categories of operations performed on data. Perform unary and binary logic operations

More information

1. NUMBER SYSTEMS USED IN COMPUTING: THE BINARY NUMBER SYSTEM

1. NUMBER SYSTEMS USED IN COMPUTING: THE BINARY NUMBER SYSTEM 1. NUMBER SYSTEMS USED IN COMPUTING: THE BINARY NUMBER SYSTEM 1.1 Introduction Given that digital logic and memory devices are based on two electrical states (on and off), it is natural to use a number

More information

carry in carry 1101 carry carry

carry in carry 1101 carry carry Chapter Binary arithmetic Arithmetic is the process of applying a mathematical operator (such as negation or addition) to one or more operands (the values being operated upon). Binary arithmetic works

More information

Number Systems and Computer Arithmetic

Number Systems and Computer Arithmetic Number Systems and Computer Arithmetic Counting to four billion two fingers at a time What do all those bits mean now? bits (011011011100010...01) instruction R-format I-format... integer data number text

More information

Lecture Notes on Contracts

Lecture Notes on Contracts Lecture Notes on Contracts 15-122: Principles of Imperative Computation Frank Pfenning Lecture 2 August 30, 2012 1 Introduction For an overview the course goals and the mechanics and schedule of the course,

More information

Math in MIPS. Subtracting a binary number from another binary number also bears an uncanny resemblance to the way it s done in decimal.

Math in MIPS. Subtracting a binary number from another binary number also bears an uncanny resemblance to the way it s done in decimal. Page < 1 > Math in MIPS Adding and Subtracting Numbers Adding two binary numbers together is very similar to the method used with decimal numbers, except simpler. When you add two binary numbers together,

More information

Overview. Introduction to the MIPS ISA. MIPS ISA Overview. Overview (2)

Overview. Introduction to the MIPS ISA. MIPS ISA Overview. Overview (2) Introduction to the MIPS ISA Overview Remember that the machine only understands very basic instructions (machine instructions) It is the compiler s job to translate your high-level (e.g. C program) into

More information

UNIT-II. Part-2: CENTRAL PROCESSING UNIT

UNIT-II. Part-2: CENTRAL PROCESSING UNIT Page1 UNIT-II Part-2: CENTRAL PROCESSING UNIT Stack Organization Instruction Formats Addressing Modes Data Transfer And Manipulation Program Control Reduced Instruction Set Computer (RISC) Introduction:

More information

Shift and Rotate Instructions

Shift and Rotate Instructions Shift and Rotate Instructions Shift and rotate instructions facilitate manipulations of data (that is, modifying part of a 32-bit data word). Such operations might include: Re-arrangement of bytes in a

More information

unused unused unused unused unused unused

unused unused unused unused unused unused BCD numbers. In some applications, such as in the financial industry, the errors that can creep in due to converting numbers back and forth between decimal and binary is unacceptable. For these applications

More information

Congruence Arithmetic

Congruence Arithmetic Module 4 Congruence Arithmetic Popper 4 Introduction to what is like Modulus choices Partitions by modulus Mod 5 Mod 7 Mod 30 Modular Arithmetic Addition Subtraction Multiplication INTEGERS! Mod 12 Cayley

More information

COMP 122/L Lecture 2. Kyle Dewey

COMP 122/L Lecture 2. Kyle Dewey COMP 122/L Lecture 2 Kyle Dewey Outline Operations on binary values AND, OR, XOR, NOT Bit shifting (left, two forms of right) Addition Subtraction Twos complement Bitwise Operations Bitwise AND Similar

More information

Lecture Notes: Widening Operators and Collecting Semantics

Lecture Notes: Widening Operators and Collecting Semantics Lecture Notes: Widening Operators and Collecting Semantics 15-819O: Program Analysis (Spring 2016) Claire Le Goues clegoues@cs.cmu.edu 1 A Collecting Semantics for Reaching Definitions The approach to

More information

Lecture 1 Contracts : Principles of Imperative Computation (Fall 2018) Frank Pfenning

Lecture 1 Contracts : Principles of Imperative Computation (Fall 2018) Frank Pfenning Lecture 1 Contracts 15-122: Principles of Imperative Computation (Fall 2018) Frank Pfenning In these notes we review contracts, which we use to collectively denote function contracts, loop invariants,

More information

Lecture Notes on Value Propagation

Lecture Notes on Value Propagation Lecture Notes on Value Propagation 15-411: Compiler Design Frank Pfenning, Rob Simmons Lecture 17 October 27, 2015 1 Introduction The opportunities for optimizations 1 in compiler-generated code are plentiful.

More information

Lecture 1 Contracts. 1 A Mysterious Program : Principles of Imperative Computation (Spring 2018) Frank Pfenning

Lecture 1 Contracts. 1 A Mysterious Program : Principles of Imperative Computation (Spring 2018) Frank Pfenning Lecture 1 Contracts 15-122: Principles of Imperative Computation (Spring 2018) Frank Pfenning In these notes we review contracts, which we use to collectively denote function contracts, loop invariants,

More information

Module 2: Computer Arithmetic

Module 2: Computer Arithmetic Module 2: Computer Arithmetic 1 B O O K : C O M P U T E R O R G A N I Z A T I O N A N D D E S I G N, 3 E D, D A V I D L. P A T T E R S O N A N D J O H N L. H A N N E S S Y, M O R G A N K A U F M A N N

More information

Arithmetic and Bitwise Operations on Binary Data

Arithmetic and Bitwise Operations on Binary Data Arithmetic and Bitwise Operations on Binary Data CSCI 2400: Computer Architecture ECE 3217: Computer Architecture and Organization Instructor: David Ferry Slides adapted from Bryant & O Hallaron s slides

More information

4 Operations On Data 4.1. Foundations of Computer Science Cengage Learning

4 Operations On Data 4.1. Foundations of Computer Science Cengage Learning 4 Operations On Data 4.1 Foundations of Computer Science Cengage Learning Objectives After studying this chapter, the student should be able to: List the three categories of operations performed on data.

More information

Basic operators, Arithmetic, Relational, Bitwise, Logical, Assignment, Conditional operators. JAVA Standard Edition

Basic operators, Arithmetic, Relational, Bitwise, Logical, Assignment, Conditional operators. JAVA Standard Edition Basic operators, Arithmetic, Relational, Bitwise, Logical, Assignment, Conditional operators JAVA Standard Edition Java - Basic Operators Java provides a rich set of operators to manipulate variables.

More information

ASSEMBLY LANGUAGE MACHINE ORGANIZATION

ASSEMBLY LANGUAGE MACHINE ORGANIZATION ASSEMBLY LANGUAGE MACHINE ORGANIZATION CHAPTER 3 1 Sub-topics The topic will cover: Microprocessor architecture CPU processing methods Pipelining Superscalar RISC Multiprocessing Instruction Cycle Instruction

More information

A Propagation Engine for GCC

A Propagation Engine for GCC A Propagation Engine for GCC Diego Novillo Red Hat Canada dnovillo@redhat.com May 1, 2005 Abstract Several analyses and transformations work by propagating known values and attributes throughout the program.

More information

Technische Universität München Zentrum Mathematik

Technische Universität München Zentrum Mathematik Technische Universität München Zentrum Mathematik Prof. Dr. Dr. Jürgen Richter-Gebert, Bernhard Werner Projective Geometry SS 208 https://www-m0.ma.tum.de/bin/view/lehre/ss8/pgss8/webhome Solutions for

More information

CS Introduction to Data Structures How to Parse Arithmetic Expressions

CS Introduction to Data Structures How to Parse Arithmetic Expressions CS3901 - Introduction to Data Structures How to Parse Arithmetic Expressions Lt Col Joel Young One of the common task required in implementing programming languages, calculators, simulation systems, and

More information

Math 340 Fall 2014, Victor Matveev. Binary system, round-off errors, loss of significance, and double precision accuracy.

Math 340 Fall 2014, Victor Matveev. Binary system, round-off errors, loss of significance, and double precision accuracy. Math 340 Fall 2014, Victor Matveev Binary system, round-off errors, loss of significance, and double precision accuracy. 1. Bits and the binary number system A bit is one digit in a binary representation

More information

More Natural Arithmetic in C++

More Natural Arithmetic in C++ More Natural Arithmetic in C++ Document number: P0999R0 Date: 2018 04 01 Reply to: James Dennett < jdennett@google.com > Audience: SG6, SG12, EWG, CWG. Synopsis A minor change to the rules of arithmetic

More information

Numbers and Computers. Debdeep Mukhopadhyay Assistant Professor Dept of Computer Sc and Engg IIT Madras

Numbers and Computers. Debdeep Mukhopadhyay Assistant Professor Dept of Computer Sc and Engg IIT Madras Numbers and Computers Debdeep Mukhopadhyay Assistant Professor Dept of Computer Sc and Engg IIT Madras 1 Think of a number between 1 and 15 8 9 10 11 12 13 14 15 4 5 6 7 12 13 14 15 2 3 6 7 10 11 14 15

More information

Number Systems and Their Representations

Number Systems and Their Representations Number Representations Cptr280 Dr Curtis Nelson Number Systems and Their Representations In this presentation you will learn about: Representation of numbers in computers; Signed vs. unsigned numbers;

More information

Selecting Attributes for Automated Clustering of Disassembled Code from Embedded Systems

Selecting Attributes for Automated Clustering of Disassembled Code from Embedded Systems Bachelor Thesis Immanuel Wietreich Selecting Attributes for Automated Clustering of Disassembled Code from Embedded Systems February 14, 2014 supervised by: Prof. Dr. Sibylle Schupp Dipl. Ing. Arne Wichmann

More information

CPE 323 REVIEW DATA TYPES AND NUMBER REPRESENTATIONS IN MODERN COMPUTERS

CPE 323 REVIEW DATA TYPES AND NUMBER REPRESENTATIONS IN MODERN COMPUTERS CPE 323 REVIEW DATA TYPES AND NUMBER REPRESENTATIONS IN MODERN COMPUTERS Aleksandar Milenković The LaCASA Laboratory, ECE Department, The University of Alabama in Huntsville Email: milenka@uah.edu Web:

More information

Project 3: RPN Calculator

Project 3: RPN Calculator ECE267 @ UIC, Spring 2012, Wenjing Rao Project 3: RPN Calculator What to do: Ask the user to input a string of expression in RPN form (+ - * / ), use a stack to evaluate the result and display the result

More information

CPE 323 REVIEW DATA TYPES AND NUMBER REPRESENTATIONS IN MODERN COMPUTERS

CPE 323 REVIEW DATA TYPES AND NUMBER REPRESENTATIONS IN MODERN COMPUTERS CPE 323 REVIEW DATA TYPES AND NUMBER REPRESENTATIONS IN MODERN COMPUTERS Aleksandar Milenković The LaCASA Laboratory, ECE Department, The University of Alabama in Huntsville Email: milenka@uah.edu Web:

More information

Arithmetic for Computers

Arithmetic for Computers MIPS Arithmetic Instructions Cptr280 Dr Curtis Nelson Arithmetic for Computers Operations on integers Addition and subtraction; Multiplication and division; Dealing with overflow; Signed vs. unsigned numbers.

More information

Signed umbers. Sign/Magnitude otation

Signed umbers. Sign/Magnitude otation Signed umbers So far we have discussed unsigned number representations. In particular, we have looked at the binary number system and shorthand methods in representing binary codes. With m binary digits,

More information

UNIT - I: COMPUTER ARITHMETIC, REGISTER TRANSFER LANGUAGE & MICROOPERATIONS

UNIT - I: COMPUTER ARITHMETIC, REGISTER TRANSFER LANGUAGE & MICROOPERATIONS UNIT - I: COMPUTER ARITHMETIC, REGISTER TRANSFER LANGUAGE & MICROOPERATIONS (09 periods) Computer Arithmetic: Data Representation, Fixed Point Representation, Floating Point Representation, Addition and

More information

Arithmetic Operators There are two types of operators: binary and unary Binary operators:

Arithmetic Operators There are two types of operators: binary and unary Binary operators: Verilog operators operate on several data types to produce an output Not all Verilog operators are synthesible (can produce gates) Some operators are similar to those in the C language Remember, you are

More information

CSIS1120A. 10. Instruction Set & Addressing Mode. CSIS1120A 10. Instruction Set & Addressing Mode 1

CSIS1120A. 10. Instruction Set & Addressing Mode. CSIS1120A 10. Instruction Set & Addressing Mode 1 CSIS1120A 10. Instruction Set & Addressing Mode CSIS1120A 10. Instruction Set & Addressing Mode 1 Elements of a Machine Instruction Operation Code specifies the operation to be performed, e.g. ADD, SUB

More information

}w!"#$%&'()+,-./012345<ya

}w!#$%&'()+,-./012345<ya MASARYKOVA UNIVERZITA FAKULTA INFORMATIKY }w!"#$%&'()+,-./012345

More information

Chapter 3: Theory of Modular Arithmetic 1. Chapter 3: Theory of Modular Arithmetic

Chapter 3: Theory of Modular Arithmetic 1. Chapter 3: Theory of Modular Arithmetic Chapter 3: Theory of Modular Arithmetic 1 Chapter 3: Theory of Modular Arithmetic SECTION A Introduction to Congruences By the end of this section you will be able to deduce properties of large positive

More information

Lecture 8: Addition, Multiplication & Division

Lecture 8: Addition, Multiplication & Division Lecture 8: Addition, Multiplication & Division Today s topics: Signed/Unsigned Addition Multiplication Division 1 Signed / Unsigned The hardware recognizes two formats: unsigned (corresponding to the C

More information

ECE Digital System Design & Synthesis Exercise 1 - Logic Values, Data Types & Operators - With Answers

ECE Digital System Design & Synthesis Exercise 1 - Logic Values, Data Types & Operators - With Answers ECE 601 - Digital System Design & Synthesis Exercise 1 - Logic Values, Data Types & Operators - With Answers Fall 2001 Final Version (Important changes from original posted Exercise 1 shown in color) Variables

More information

2. Define Instruction Set Architecture. What are its two main characteristics? Be precise!

2. Define Instruction Set Architecture. What are its two main characteristics? Be precise! Chapter 1: Computer Abstractions and Technology 1. Assume two processors, a CISC processor and a RISC processor. In order to run a particular program, the CISC processor must execute 10 million instructions

More information

Arithmetic Operations on Binary Numbers

Arithmetic Operations on Binary Numbers Arithmetic Operations on Binary Numbers Because of its widespread use, we will concentrate on addition and subtraction for Two's Complement representation. The nice feature with Two's Complement is that

More information

Programming in C++ 5. Integral data types

Programming in C++ 5. Integral data types Programming in C++ 5. Integral data types! Introduction! Type int! Integer multiplication & division! Increment & decrement operators! Associativity & precedence of operators! Some common operators! Long

More information

Chapter 1 Summary. Chapter 2 Summary. end of a string, in which case the string can span multiple lines.

Chapter 1 Summary. Chapter 2 Summary. end of a string, in which case the string can span multiple lines. Chapter 1 Summary Comments are indicated by a hash sign # (also known as the pound or number sign). Text to the right of the hash sign is ignored. (But, hash loses its special meaning if it is part of

More information

Problem with Scanning an Infix Expression

Problem with Scanning an Infix Expression Operator Notation Consider the infix expression (X Y) + (W U), with parentheses added to make the evaluation order perfectly obvious. This is an arithmetic expression written in standard form, called infix

More information

DIGITAL ARITHMETIC: OPERATIONS AND CIRCUITS

DIGITAL ARITHMETIC: OPERATIONS AND CIRCUITS C H A P T E R 6 DIGITAL ARITHMETIC: OPERATIONS AND CIRCUITS OUTLINE 6- Binary Addition 6-2 Representing Signed Numbers 6-3 Addition in the 2 s- Complement System 6-4 Subtraction in the 2 s- Complement

More information

UNIVERSITY OF MASSACHUSETTS Dept. of Electrical & Computer Engineering. Digital Computer Arithmetic ECE 666

UNIVERSITY OF MASSACHUSETTS Dept. of Electrical & Computer Engineering. Digital Computer Arithmetic ECE 666 UNIVERSITY OF MASSACHUSETTS Dept. of Electrical & Computer Engineering Digital Computer Arithmetic ECE 666 Part 4-A Floating-Point Arithmetic Israel Koren ECE666/Koren Part.4a.1 Preliminaries - Representation

More information

Week - 04 Lecture - 01 Merge Sort. (Refer Slide Time: 00:02)

Week - 04 Lecture - 01 Merge Sort. (Refer Slide Time: 00:02) Programming, Data Structures and Algorithms in Python Prof. Madhavan Mukund Department of Computer Science and Engineering Indian Institute of Technology, Madras Week - 04 Lecture - 01 Merge Sort (Refer

More information

4 Operations On Data 4.1. Foundations of Computer Science Cengage Learning

4 Operations On Data 4.1. Foundations of Computer Science Cengage Learning 4 Operations On Data 4.1 Foundations of Computer Science Cengage Learning Objectives After studying this chapter, the student should be able to: List the three categories of operations performed on data.

More information

Chapter 10 - Computer Arithmetic

Chapter 10 - Computer Arithmetic Chapter 10 - Computer Arithmetic Luis Tarrataca luis.tarrataca@gmail.com CEFET-RJ L. Tarrataca Chapter 10 - Computer Arithmetic 1 / 126 1 Motivation 2 Arithmetic and Logic Unit 3 Integer representation

More information

CS/COE0447: Computer Organization

CS/COE0447: Computer Organization CS/COE0447: Computer Organization and Assembly Language Chapter 3 Sangyeun Cho Dept. of Computer Science Five classic components I am like a control tower I am like a pack of file folders I am like a conveyor

More information

Logic, Words, and Integers

Logic, Words, and Integers Computer Science 52 Logic, Words, and Integers 1 Words and Data The basic unit of information in a computer is the bit; it is simply a quantity that takes one of two values, 0 or 1. A sequence of k bits

More information

Topic Notes: Bits and Bytes and Numbers

Topic Notes: Bits and Bytes and Numbers Computer Science 220 Assembly Language & Comp Architecture Siena College Fall 2011 Topic Notes: Bits and Bytes and Numbers Binary Basics At least some of this will be review for most of you, but we start

More information

CS/COE0447: Computer Organization

CS/COE0447: Computer Organization Five classic components CS/COE0447: Computer Organization and Assembly Language I am like a control tower I am like a pack of file folders Chapter 3 I am like a conveyor belt + service stations I exchange

More information

A.1 Numbers, Sets and Arithmetic

A.1 Numbers, Sets and Arithmetic 522 APPENDIX A. MATHEMATICS FOUNDATIONS A.1 Numbers, Sets and Arithmetic Numbers started as a conceptual way to quantify count objects. Later, numbers were used to measure quantities that were extensive,

More information

COMPUTER ORGANIZATION AND DESIGN. 5 th Edition. The Hardware/Software Interface. Chapter 3. Arithmetic for Computers Implementation

COMPUTER ORGANIZATION AND DESIGN. 5 th Edition. The Hardware/Software Interface. Chapter 3. Arithmetic for Computers Implementation COMPUTER ORGANIZATION AND DESIGN The Hardware/Software Interface 5 th Edition Chapter 3 Arithmetic for Computers Implementation Today Review representations (252/352 recap) Floating point Addition: Ripple

More information

CS401 - Computer Architecture and Assembly Language Programming Glossary By

CS401 - Computer Architecture and Assembly Language Programming Glossary By CS401 - Computer Architecture and Assembly Language Programming Glossary By absolute address : A virtual (not physical) address within the process address space that is computed as an absolute number.

More information

2.1. Unit 2. Integer Operations (Arithmetic, Overflow, Bitwise Logic, Shifting)

2.1. Unit 2. Integer Operations (Arithmetic, Overflow, Bitwise Logic, Shifting) 2.1 Unit 2 Integer Operations (Arithmetic, Overflow, Bitwise Logic, Shifting) 2.2 Skills & Outcomes You should know and be able to apply the following skills with confidence Perform addition & subtraction

More information

What Every Programmer Should Know About Floating-Point Arithmetic

What Every Programmer Should Know About Floating-Point Arithmetic What Every Programmer Should Know About Floating-Point Arithmetic Last updated: October 15, 2015 Contents 1 Why don t my numbers add up? 3 2 Basic Answers 3 2.1 Why don t my numbers, like 0.1 + 0.2 add

More information

But first, encode deck of cards. Integer Representation. Two possible representations. Two better representations WELLESLEY CS 240 9/8/15

But first, encode deck of cards. Integer Representation. Two possible representations. Two better representations WELLESLEY CS 240 9/8/15 Integer Representation Representation of integers: unsigned and signed Sign extension Arithmetic and shifting Casting But first, encode deck of cards. cards in suits How do we encode suits, face cards?

More information

Chapter 3: part 3 Binary Subtraction

Chapter 3: part 3 Binary Subtraction Chapter 3: part 3 Binary Subtraction Iterative combinational circuits Binary adders Half and full adders Ripple carry and carry lookahead adders Binary subtraction Binary adder-subtractors Signed binary

More information

Calvin Lin The University of Texas at Austin

Calvin Lin The University of Texas at Austin Loop Invariant Code Motion Last Time SSA Today Loop invariant code motion Reuse optimization Next Time More reuse optimization Common subexpression elimination Partial redundancy elimination February 23,

More information

Computer Architecture and System Software Lecture 02: Overview of Computer Systems & Start of Chapter 2

Computer Architecture and System Software Lecture 02: Overview of Computer Systems & Start of Chapter 2 Computer Architecture and System Software Lecture 02: Overview of Computer Systems & Start of Chapter 2 Instructor: Rob Bergen Applied Computer Science University of Winnipeg Announcements Website is up

More information

A Linear-Time Heuristic for Improving Network Partitions

A Linear-Time Heuristic for Improving Network Partitions A Linear-Time Heuristic for Improving Network Partitions ECE 556 Project Report Josh Brauer Introduction The Fiduccia-Matteyses min-cut heuristic provides an efficient solution to the problem of separating

More information

Topic Notes: Bits and Bytes and Numbers

Topic Notes: Bits and Bytes and Numbers Computer Science 220 Assembly Language & Comp Architecture Siena College Fall 2010 Topic Notes: Bits and Bytes and Numbers Binary Basics At least some of this will be review, but we will go over it for

More information

Language Reference Manual simplicity

Language Reference Manual simplicity Language Reference Manual simplicity Course: COMS S4115 Professor: Dr. Stephen Edwards TA: Graham Gobieski Date: July 20, 2016 Group members Rui Gu rg2970 Adam Hadar anh2130 Zachary Moffitt znm2104 Suzanna

More information

EE 486 Winter The role of arithmetic. EE 486 : lecture 1, the integers. SIA Roadmap - 2. SIA Roadmap - 1

EE 486 Winter The role of arithmetic. EE 486 : lecture 1, the integers. SIA Roadmap - 2. SIA Roadmap - 1 EE 486 Winter 2-3 The role of arithmetic EE 486 : lecture, the integers M. J. Flynn With increasing circuit density available with sub micron feature sizes, there s a corresponding broader spectrum of

More information

CPE300: Digital System Architecture and Design

CPE300: Digital System Architecture and Design CPE300: Digital System Architecture and Design Fall 2011 MW 17:30-18:45 CBC C316 Arithmetic Unit 10122011 http://www.egr.unlv.edu/~b1morris/cpe300/ 2 Outline Recap Fixed Point Arithmetic Addition/Subtraction

More information

Technische Universität München Zentrum Mathematik

Technische Universität München Zentrum Mathematik Question 1. Incidence matrix with gaps Technische Universität München Zentrum Mathematik Prof. Dr. Dr. Jürgen Richter-Gebert, Bernhard Werner Projective Geometry SS 2016 www-m10.ma.tum.de/projektivegeometriess16

More information

Module 2: Classical Algorithm Design Techniques

Module 2: Classical Algorithm Design Techniques Module 2: Classical Algorithm Design Techniques Dr. Natarajan Meghanathan Associate Professor of Computer Science Jackson State University Jackson, MS 39217 E-mail: natarajan.meghanathan@jsums.edu Module

More information

Floating-Point Arithmetic

Floating-Point Arithmetic ENEE446---Lectures-4/10-15/08 A. Yavuz Oruç Professor, UMD, College Park Copyright 2007 A. Yavuz Oruç. All rights reserved. Floating-Point Arithmetic Integer or fixed-point arithmetic provides a complete

More information

MIPS Integer ALU Requirements

MIPS Integer ALU Requirements MIPS Integer ALU Requirements Add, AddU, Sub, SubU, AddI, AddIU: 2 s complement adder/sub with overflow detection. And, Or, Andi, Ori, Xor, Xori, Nor: Logical AND, logical OR, XOR, nor. SLTI, SLTIU (set

More information

Rui Wang, Assistant professor Dept. of Information and Communication Tongji University.

Rui Wang, Assistant professor Dept. of Information and Communication Tongji University. Instructions: ti Language of the Computer Rui Wang, Assistant professor Dept. of Information and Communication Tongji University it Email: ruiwang@tongji.edu.cn Computer Hierarchy Levels Language understood

More information

COMP2611: Computer Organization. Data Representation

COMP2611: Computer Organization. Data Representation COMP2611: Computer Organization Comp2611 Fall 2015 2 1. Binary numbers and 2 s Complement Numbers 3 Bits: are the basis for binary number representation in digital computers What you will learn here: How

More information

MIPS Instruction Set

MIPS Instruction Set MIPS Instruction Set Prof. James L. Frankel Harvard University Version of 7:12 PM 3-Apr-2018 Copyright 2018, 2017, 2016, 201 James L. Frankel. All rights reserved. CPU Overview CPU is an acronym for Central

More information

COMPUTER ARCHITECTURE AND ORGANIZATION Register Transfer and Micro-operations 1. Introduction A digital system is an interconnection of digital

COMPUTER ARCHITECTURE AND ORGANIZATION Register Transfer and Micro-operations 1. Introduction A digital system is an interconnection of digital Register Transfer and Micro-operations 1. Introduction A digital system is an interconnection of digital hardware modules that accomplish a specific information-processing task. Digital systems vary in

More information

Divide: Paper & Pencil

Divide: Paper & Pencil Divide: Paper & Pencil 1001 Quotient Divisor 1000 1001010 Dividend -1000 10 101 1010 1000 10 Remainder See how big a number can be subtracted, creating quotient bit on each step Binary => 1 * divisor or

More information

Arithmetic Circuits. Design of Digital Circuits 2014 Srdjan Capkun Frank K. Gürkaynak.

Arithmetic Circuits. Design of Digital Circuits 2014 Srdjan Capkun Frank K. Gürkaynak. Arithmetic Circuits Design of Digital Circuits 2014 Srdjan Capkun Frank K. Gürkaynak http://www.syssec.ethz.ch/education/digitaltechnik_14 Adapted from Digital Design and Computer Architecture, David Money

More information

CS 253. January 14, 2017

CS 253. January 14, 2017 CS 253 Department of Computer Science College of Engineering Boise State University January 14, 2017 1/30 Motivation Most programming tasks can be implemented using abstractions (e.g. representing data

More information

CSCI 2212: Intermediate Programming / C Chapter 15

CSCI 2212: Intermediate Programming / C Chapter 15 ... /34 CSCI 222: Intermediate Programming / C Chapter 5 Alice E. Fischer October 9 and 2, 25 ... 2/34 Outline Integer Representations Binary Integers Integer Types Bit Operations Applying Bit Operations

More information

Chapter 2. Positional number systems. 2.1 Signed number representations Signed magnitude

Chapter 2. Positional number systems. 2.1 Signed number representations Signed magnitude Chapter 2 Positional number systems A positional number system represents numeric values as sequences of one or more digits. Each digit in the representation is weighted according to its position in the

More information

IEEE Standard 754 Floating Point Numbers

IEEE Standard 754 Floating Point Numbers IEEE Standard 754 Floating Point Numbers Steve Hollasch / Last update 2005-Feb-24 IEEE Standard 754 floating point is the most common representation today for real numbers on computers, including Intel-based

More information

(Refer Slide Time: 1:40)

(Refer Slide Time: 1:40) Computer Architecture Prof. Anshul Kumar Department of Computer Science and Engineering, Indian Institute of Technology, Delhi Lecture - 3 Instruction Set Architecture - 1 Today I will start discussion

More information

GO - OPERATORS. This tutorial will explain the arithmetic, relational, logical, bitwise, assignment and other operators one by one.

GO - OPERATORS. This tutorial will explain the arithmetic, relational, logical, bitwise, assignment and other operators one by one. http://www.tutorialspoint.com/go/go_operators.htm GO - OPERATORS Copyright tutorialspoint.com An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations.

More information

Sendmail crackaddr - Static Analysis strikes back

Sendmail crackaddr - Static Analysis strikes back Sendmail crackaddr - Static Analysis strikes back Bogdan Mihaila Technical University of Munich, Germany December 6, 2014 Name Lastname < name@mail.org > ()()()()()()()()()... ()()() 1 / 25 Abstract Interpretation

More information

CS 64 Week 1 Lecture 1. Kyle Dewey

CS 64 Week 1 Lecture 1. Kyle Dewey CS 64 Week 1 Lecture 1 Kyle Dewey Overview Bitwise operation wrap-up Two s complement Addition Subtraction Multiplication (if time) Bitwise Operation Wrap-up Shift Left Move all the bits N positions to

More information

NAN propagation versus fault trapping in floating point code

NAN propagation versus fault trapping in floating point code NAN propagation versus fault trapping in floating point code By Agner Fog. Technical University of Denmark. Copyright 2018. Last updated 2018-05-24. Contents 1 Introduction... 1 2 Fault trapping... 1 3

More information

Lattice Tutorial Version 1.0

Lattice Tutorial Version 1.0 Lattice Tutorial Version 1.0 Nenad Jovanovic Secure Systems Lab www.seclab.tuwien.ac.at enji@infosys.tuwien.ac.at November 3, 2005 1 Introduction This tutorial gives an introduction to a number of concepts

More information