Mathematical computations in C language |
|||
Computation | C syntax | Assembly equivalence | Notes |
Assign value | Alfa = 5; | mov [Alfa], 5 | ... |
Addition |
Alfa = Alfa + 5; Alfa += 5; Alfa = Beta + 5; |
add [alfa], 5 add [alfa], 5 mov eax, [beta] add eax, 5 mov [alfa], eax |
The double operator "+=" it used when we add a number to a variable. In this case type: Alfa = Alfa + 5; or Alfa += 5; gets the same result |
Subtraction |
Alfa = Alfa - 5; Alfa -= 5; Alfa = Beta - 5; |
sub [Alfa], 5 sub [Alfa], 5 mov eax, [Beta] sub eax, 5 mov [Alfa], eax |
The double operator "-=" is used when a value is subtracted to a variable. The instruction Alfa = Alfa -5; is the same than Alfa -= 5; |
Multiplication |
Alfa = Alfa * 12 Alfa *= 12; Alfa = Beta * 12; |
mov eax, [Alfa] imul eax, 12 mov [alfa], eax mov eax, [beta] imul eax, 12 mov [alfa], eax |
The double operator "*=" is when you mulitply a variable the same variable you use as result. Alfa *= 12; is the same that Alfa = Alfa * 12; |
Division |
Alfa = Alfa / 23; Alfa /= 23; Alfa = Beta / 23; |
mov eax, [alfa] idiv 23 mov [alfa], eax mov eax, [beta] idiv 23 mov [alfa], eax |
The double operator "/=" is quando you divide a variable for a value and the you put the result in same variable. Alfa = Alfa / 3; is the same that: Alfa /= 3; |
Remainder of division | Remainder = Alfa % 5; |
mov ecx, [Alfa] idiv ecx, 5 mov [Remainder], dx |
Example: 23 / 5 = 4 with remainder =3 In assembly the remainder of a divsion (DIV or IDIV instructions) is always stored in DX register |
Power (square) |
Result = Alfa * Alfa; Result = pow(Alfa, 2.0); |
mov ecx, [alfa] imul ecx, ecx mov [result], eax .... |
pow() is an external function, this means you have to include the source of this function, in your file. If you get an error when you use pow() in your C function, you have to type at top of your source (after the other #include directives) the row: #include <math.h> note: pow() function want arguments and result in double format. The double is alike float but with an higher precision. Anyway we can convert any number in double, and the result in float or int See the description about type conversion |
Power raised to n |
Result = pow(alfa, 7); Result = pow(alfa, 4); |
..... ..... |
See notes of Power (square) |
Square root | Alfa = sqrt(Beta); | ....... |
sqrt() is an external function, this means you have to include the source of this function, in your file. If you get an error when you use sqrt() in your C function, you have to type at top of your source (after the other #include directives) the row: #include <math.h> note: sqrt() function want argument and give the result in double format. The double is alike float but with an higher precision. Anyway we can convert any number in double, and the result in float or int See the description about type conversion |
returns a value |
return Alfa; return Alfa+Beta; |
mov eax, [Alfa] ret mov eax, [Beta] add eax, [Alfa] ret |
In the reality the returning value is not a computation anyway it's interesting remember that when a function computes some value (or address) then it will have to return it to the caller code. In a C function you use the return instruction to set what value place in eax register before exiting and coming back to the caller code. In assembly we'use the eax code, too, but in this case we have also to place the ret instruction. Note: remember that the assembly instruction: ret 32 is not like, C instruction: return 32; The ret assembly instruction followed on same row by a number doesn't return that value in eax but it uses that value to compute how much bytes extract from the stack. In the 32 flat assembly it's better never use ret in that syntax. To return a value for caller code we'll use the syntax: mov eax, 32 ret |
Shift at left |
Alfa = Alfa << 4; Alfa = Beta << 1; |
shl [Alfa],4 mov eax, [Beta] shl eax, 1 mov [Alfa], eax |
... |
Shift at right |
Alfa = Alfa >> 4; Alfa = Beta >> 1; |
shr [Alfa], 4 mov eax, [Beta] shr eax, 1 mov [Alfa], eax |
... |
Increment by 1 | Alfa++; | inc [Alfa] | ... |
Decrement by 1 | Alfa--; | dec [Alfa] | ... |
and |
Alfa = Alfa & 7; Alfa &= 7; Alfa = Beta & 1; |
and [Alfa], 7 and [Alfa], 7 mov eax, [Beta] and eax, 1 mov [Alfa], eax |
... |
or |
Alfa = Alfa | 5; Alfa |= 5; Alfa = Beta | 3; |
or [Alfa], 5 or [Alfa], 5 mov eax, [Beta] or eax, 3 mov [Alfa], eax |
... |
exclusive or |
Alfa = Alfa ^ 4; Alfa ^= 4; Alfa = Beta ^ 8; |
xor [Alfa], 4 xor [Alfa], 4 mov eax, [beta] xor eax, 8 mov [alfa], eax |
... |
Not One's complement |
Alfa = ~4; Alfa = ~Alfa; Alfa = ~Beta; |
mov [Alfa], ~4 not [Alfa] mov eax, [Beta] not eax mov [Alfa], eax |
The not is an unary operator, for this reason has no sense the istruction: Alfa = Beta ~ 4 Pheraps when you type above istruction you meant: Alfa = Beta & ~4 The complement's one is apparently a weird operation but it is very useful when we wish clear a single bit (or more bits) indifferently by its previous state. If we wish clear the bit with value 8 in the variable [Alfa] we can perform an and with the complement's one of 8 Alfa = Alfa & ~8; or in syntetic form: Alfa &= ~8; and now the bit with value 8 will be 0 This is named "applying a bit mask" In assembly it will be and [Alfa], ~8 Note: the complement's one is like performing a XOR -1 on that value |
Sign inversion |
Alfa = -Alfa; Alfa = -Beta; |
neg [Alfa] mov eax, [Beta] neg eax mov [Alfa], eax |
... |
Get address of variable | ptrMyVariable = &Alfa; |
lea eax, Alfa mov [ptrMyVariable], eax |
The & operator, when used as unary operator at left of a variable, returns the address of that variable, rather than its value. Note that in assembly it's possible also to do that, using the syntax: mov eax, offset Alfa and it works like: lea eax, Alfa When you type the keyword "offset" in front of a variable you mean own "I want the address, rather than internal value, of this variable" in this case we could say that the precise assembly equivalence of the C++ "&" operator is own the "offset" keyword. Anyway, in assembly, when in the right operand there are also registers it's better using the lea instruction: lea eax, Alfa[ecx*2] |
The conditional operators used with IF |
||
Operator | Example | Description |
is equal == |
if (x == 0) ... |
A common error,of beginners about C language, is to use the single "=" sign to compare two values, while in C the single = sign is only for assignments, while for comparison we have to use the double equal ==. The problem is that, by default, the compiler doesn't give any mexage because it could be a valid instruction in seldom circustances (assigning a value and verify its content in same moment) Anyway if the compiler doens't warn you it's almost sure that you'll mistake very often using the assignemnt operator. To avoid this problem it's necessary type at top of each source of your project, this pragma directive: #pragma warning( error : 4706 ) Above directive tells to the compiler: "if I use an assignment in a IF condition, please say me that I mistaked with an error mexage" The error mexage that it will be showed is: error C4706: assignment within conditional expression And now just performing a double click on that error mexage to see the row where you mistaked. Remark: I've already inserted above pragma directive in all sources of your plugin, anyway if you'll add new sources to your plugin project, remember to insert also in these that directive. |
is greater than > |
if (x > y) ... |
If first operand is greater than second. Note that if the two operands are equal the condition will be false. |
is greater or equal >= |
if (x >= y) ... |
if first operand is greater or equal than second, the condition is true Please, note that it's not the same thing inverting the position of the two signs: this is correct: if (x >= y) ... while this: if (x => y) ... is a syntax error. |
is less than < |
if (x < y) ... | When the first operand is less than second, the condition is true |
is less or equal than... <= |
if (x <= y) ... |
When the first operand is less or equal than second, the condition is true. Remember you cann't change the position of the two signs. The only correct syntax is: <= while this: =< is a syntax error |
is different than != |
if (x != y) ... |
The "!=" is the opposite of "==". If the two operands are different then the condition is true. Note that in C language doesn't exist the "greater or less" operator that in some language (like visual basic) works in this way: if (x <> 3) ... Above syntax in C language is only a syntax error. You have to use the != operator: if (x != 3) ... |
not ! |
if ( !x ) .... |
The not "!" is an unary operator, it inverts the boolean value of the variable at its right. To understand this operator it's necessary remember that when we test a variable omiting any conditional operator, the condition will be true if that variable is different than zero, while the condition will be false if the variable is zero. For example: int a; a=3; if (a) { } in above code the condition is true because value of a is 3, i.e. not zero, i.e. it is true. If we place a not "!" in front of that variable: if (!a) { // code to perform when a is false (it is equal than 0) } The not operator inverts the result of a condition: if it was true, it becomes false and vice versa. This operator works fine also with macro conditions grouped in parenthesis. if (!(a > 3 || a < -3)) { // the condtion will be true, and this code will be performed, // when (a <= 3 && a >= -3) } |
and bits & |
if (x & 1) ... |
The single & character, used as binary operator, works like an AND to test the single bits of the two operands. It works like the TEST assembly instruction. You use the binary & when you wish perform a condition about the single bits of a variable. Example: WORD Mask; Mask = 10; if (Mask & 2) { // the condition is true because 10 is 8 + 2 bit values, so the bit // value 2 is present } Just that at least one bit was present in both operand two give a true result. |
and conditions && |
if (x == 3 && y == 0) ... |
The conditional and "&&" permits to link two or more condition, the result will be true if all the conditions are true. example: a=3; b=5; c=0; if (a > 1 && b < 6 && c !=0) { } above condition is false, because "a > 1" is true, "b < 6" is true but "c != 0) is false because c had to be different than zero to be true the condition. We can use also nested round parenthesis to group complicated conditions if (c == 0 && (a == 0 || a == 3)) above condition is true |
or conditions || |
if (a == 0 || b == 0) ... |
The conditional or "||" compares two or more conditions, the result will be true if at least one of them is true. Example: a = 4; b = 12; c = -3; if (a == 12 || b == 12 || c == 0) ... Above condition is true, because the sub-condition "b == 12" is true and, in spite of the others are false, with the or just that one OR another was true to get true the whole condition. |
char *ControlValues(int *pVetValues)
{
int i;
int CurrentValue;
char *pMessage;
pMessage = "That's ok";
for (i=0;i<100;i++) {
CurrentValue = pVetValues[i];
if (CurrentValue < 0) {
pMessage = "ERROR: invalid value less than zero";
break;
}
// other code to manage the currentvalue
}
return pMessage;
}
void GetMaxValue(int Arg1, int Arg2)
{
int MaxValue;
int SwapValue;
MaxValue=-1;
if (Arg1 > MaxValue) MaxValue=Arg1;
if (Arg2 > MaxValue) MaxValue=Arg2;
return MaxValue;
}