Intermediate Operations |
|
#include <iostream> using namespace std; main() { const int N1 = 187; const int N2 = 242; cout << N1 << " & " << N2 << " = " << (N1 & N2) << "\n\n"; return 0; }This would produce: 187 & 242 = 178 |
|
Comparing Bits: The Bitwise OR Operator | |
You can perform another type of comparison on bits using the bitwise OR operator that is represented by |. Its syntax is: Value1 | Value2 Once again, the compiler compares the corresponding bits of each operand. If at least one of the equivalent bits is 1, the comparison produces 1. The comparison produces 0 only if both bits are 0. This operation is resumed as follows: |
|
Once again, let’s consider decimals 187 and 242. Their bitwise OR comparison would render the following result: |
|
You can also let the compiler perform the operation and produce a result. Here is an example: |
#include <iostream> using namespace std; main() { const int N1 = 187; const int N2 = 242; cout << N1 << " | " << N2 << " = " << (N1 | N2) << "\n\n"; return 0; } This would produce: 187 | 242 = 251
Comparing Bits: The Bitwise-Exclusive XOR Operator ^ |
Like the previous two operators, the bitwise-exclusive OR operator performs a bit comparison of two values. It syntax is: Value1 ^ Value2 The compiler compares the bit of one value to the corresponding bit of the other value. If one of the bits is 0 and the other is 1, the comparison produces 1. In the other two cases, that is, if both bits have the same value, the comparison produces 0. This operation is resumed as follows: |
|
We will again consider decimals 187 and 242. Their bitwise-exclusive XOR comparison would render the following result: |
|
If the compiler performs this operation, it can produce a result as in the following example: |
#include <iostream> using namespace std; main() { const int N1 = 187; const int N2 = 242; cout << N1 << " ^ " << N2 << " = " << (N1 ^ N2) << "\n\n"; } |
This would produce: |
187 ^ 242 = 73
Bit Shift Operators: The Left Shift << |
In the previous lesson, we learned that bits are aligned in some consecutive manner to store data as needed. One operation you can perform on such bits consists of moving bits in a direction of your choice. C++ provides the left shift operator represented with << and its syntax is: Value << ConstantInteger The left shift operator, <<, is a binary operator whose right operand must be a constant integer. When performing the operation, the compiler would “push” Value’s bits to the left by the number of ConstantInteger. The number of ConstantInteger bits on the left side of Value would disappear. The bits on the left side of Value would replace them. After moving to the left, the space left by the most right bits would be filled with 0 bits. Imagine you have a variable named Value and whose value is 42. The binary value of 42 is 0010 1010 (you are probably asking, "Why the hell do I need to know this?" and my answer is, "I have no idea" but you ain't got no choice; ain't no one else gonna learn this stuff for you). Imagine you want to shift Value to the left by 2 bits. You would proceed as follows: |
0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | ||
42 Shifted to the left by 2 bits << 2 | |||||||||
0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
The resulting binary number is 1010 1000 and its decimal value is 1*27 + 0*26 + 1*25 + 0*24 + 1*23 + 0*22 + 0*21 + 0*20 = 1*128 + 0*64 + 1*32 + 0*16 + 1*8 + 0*4 + 0*2 + 0*1 = 128 + 0 + 32 + 0 + 8 + 0 + 0 + 0 = 128 + 32 + 8 = 168 This can also be illustrated in the following program: |
#include <iostream> using namespace std; main() { const int Value = 42; cout << Value << " << 2 = " << (Value << 2) << "\n\n"; } |
This would produce:
42 << 2 = 168
Bit Shift Operators: The Right Shift >> |
As opposed to the left operator, the right shift moves bits to the right by a natural number. Everything is done as for the left shift except that the concept is applied to the opposed direction. |
Inline Assembly |
Introduction |
All the variables that we have used so far were declared in, and passed to, the random memory (RAM). Once a variable is declared and “put” in the memory, whenever it is involved in a calculation or assignment, the microprocessor sends a request to the memory to retrieve the value of the variable. The Central Processing Unit (CPU), also called the microprocessor, has its own memory. The microprocessor is made of memory cells called registers. Unlike the memory in the RAM, the access of the memory in the microprocessor is more precise; so precise that the registers are referred to by using their names. Some of the most commonly used registers (also called general purpose registers) are called EAX, EBX, ECX, EDX, ESI, etc. These registers are mostly used in the Assembly Language for low-level programming. Most modern compilers allow you to include Assembly Language code in your program. Using this feature, you can write a section or sections of Assembly language. When Assembly is included in your C++ program, it is referred to as Inline Assembly. |
Passing Values to Registers |
Using registers allows the programmer to write assignments directly destined for the microprocessor. The assignments and operations in the Assembly language are called instructions. When instructions are used by registers, the processing of the program is fast because the microprocessor does not have to retrieve the values of the variables in the RAM; these values, since existing in the registers, are readily available. A section that has Assembly code starts with __asm followed by some other techniques. When the compiler encounters this keyword, it knows that the subsequent code would be in Assembly language and it would treat it accordingly. For example, instead of performing a calculation in the RAM, the following program will assign values to two integer variables, namely Number1 and Number2, then it calculate their sum of those two numbers and stores the result in another variable called Result. After the calculation, the Assembly section sends the result back to the C++ compiler to display the variables and their values: |
#ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; int main( int argc, char * argv[] ) { int Number1, Number2, Result; __asm { MOV Number1, 248 // Initialize Number1 MOV Number2, 405 // Initialize Number2 MOV EAX, Number1 // Put the value of Number1 in the EAX register ADD EAX, Number2 // Add the value of Number2 to the content of EAX MOV Result, EAX // Put the content of EAX into Result } // That's it cout << "Number1 = " << Number1 << endl; cout << "Number2 = " << Number2 << endl; cout << "\nAfter adding Number1 to Number2," << endl; cout << "Result = " << Result << endl; return 0; } |
This would produce:
umber1 = 248 Number2 = 405 After adding Number1 to Number2, Result = 653 |
|
||
Previous | Copyright © 2004-2016, FunctionX | Next |
|