06 Machine Level Programming II

Control

Control of the code execution flow
Machine code provides two basic low-level mechanisms for implementing conditional behavior: (Machine code provides two basic low-level mechanisms for implementing conditional behavior)

  • It tests data values ​​and changes the control flow or data flow based on the results of these tests

6.1 Condition Codes

The CPU maintains a series of single-bit condiiton code registers describing attributes of the most recent arithmetic or logical operations
(unit condition code registers describing the attributes of the most recent arithmetic or logical operations)

  • CF: Carry Flag (carry flag) The most recent operation generated a carry out of the most significant bit (the most recent operation generated the execution of the most significant bit) ------> Mainly used to detect overflow of unsigned operations
  • ZF: Zero Flag. (Zero flag) The result of the latest operation is zero
  • SF: Sign Flag. (Sign Flag) The most recent operation produced a negative value
  • OF: Overflow Flag (overflow flag) The most recent operation caused 2's complement overflow

For example, if we have this calculation t = a + b
then these registers will be calculated like this

 CF (unsigned) t < (unsigned) a			Unsigned Overflow
 ZF (t == 0)												Zero
 SF (t < 0)													Negative
 OF (a < 0 == b < 0) && (t < 0 != a < 0) Sign Overflow

Insert image description here

6.2 Jump Instructions

  • Jump instructions are usually translated as a label, jump to this label here

if-else statement in C language

if(test-expr)
  then-statement
else
  else-statement

Assembly will convert it into the following form

t  = text-expr
if(!t)
	goto false;
then-statement
	goto done;
false:
	else-statement
done:

6.3 Use conditional transfer to implement conditional branching

The operation to achieve conditions is traditionally done through control:

  • If correct, take one path
  • On the contrary, there is another way

An alternative strategy is to use conditional transfer of data

  • In fact, I calculated both, and took whichever one was the result.
long absdiff(long x, long y){
  long result;
  if(x < y)
    result = y - x;
  else
  	result = x - y;
  return result
}

会被翻译为
long cmovdiff(long x, long y){
  long rval = y - x;
  long eval = x - y;
  long ntest = x >= y;
  
  if(ntest)	rval = eval;
  return rval;
}

The reason why conditional transfer of data has better performance is mainly because it can avoid penalties for processor errors.

  • Today's processors use very sophisticated branch prediction logic to guess whether each instruction will be executed.
  • If the prediction fails, the processor is required to discard the work it has done for all instructions after the jump instruction, and then start from the correct position to fill the pipeline

6.4 Switch statement

Multiple branch predictions can be made based on an integer index value

  • Using jump table makes the implementation more efficient

Insert image description here

Guess you like

Origin blog.csdn.net/m0_56898461/article/details/129671432