If statements, and all other control flow statements, are implemented at the logic level as conditional jumps.
When you use an if statement, like this one:
int a = 1, b = 0
if (a > b)
{
...
Obviously, any smart compiler will optimize this out. If we specifically instruct our compiler to be as dumb as possible and generate instructions verbatim, we'll get something like the following out of it:
my_if_statement:
CMP eax, ebx # intrinsically works by subtracting ebx from eax
# eax and ebx are not changed, but the arithmetic flags are
# if it was greater, jump to greater label
JG my_if_statement_was_true
# if it wasn't greater, we get here
my_if_statement_was_false:
# do something
# we're now done, so jump to the end of the statement
J my_if_statement_end
my_if_statement_was_true:
# do something else
# now we're done with the if statement
my_if_statement_end:
# program continues
These are assembly instructions, each of which translate (roughly) directly to machine code opcodes. The processor does a bunch of additional stuff to support the process of loading and fetching instructions, which is relevant here. There is a special register called the program counter (referred to later as the PC register), which tracks the location of the next opcode that the processor is going to execute.
- First, the CMP instruction subtracts the second operand from the first, and discards the result. However, the FLAGS register is updated with the results of the arithmetic operation.
- Then, the JG instruction checks whether the GREATER flag in the FLAGS register is set. Since it is in our example (recall that 1 > 0), it performs a jump.
- The jump instruction modifies the program counter (PC), which is the register that controls where the CPU will read the next instruction from.
- The CPU then attempts to read the next instruction. Since we've jumped, the next instruction is not the one immediately following the previously processed one.
That's an overview of the process. If you want a more in depth explanation, I recommend you write a simple C program with an if statement, compile it, disassemble it (using linux objdump
or an equivalent), and maybe attach a debugger to it and run it.
linux objdump
manual
To show the next instruction to be executed in gdb
, use display/i $pc