если заявления, а все другие операторы управления потоком, являются реализованы на логическом уровне как условные прыжки.
При использовании, если заявление, как этот:
int a = 1, b = 0
if (a > b)
{
...
Очевидно, что любой умный компилятор оптимизирует это. Если мы специально проинструктировать наш компилятор будет столь же глупо, как это возможно, и генерировать инструкции дословно, мы получим что-то вроде следующего из него:
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
Эти инструкции по монтажу, каждая из которых переводят (примерно) непосредственно машинный код. Процессор выполняет кучу дополнительных материалов для поддержки процесса загрузки и получения инструкций, что здесь актуально. Существует специальный регистр, называемый программным счетчиком (далее именуемый как регистр ПК), который отслеживает местоположение следующего кода операции, который будет выполняться процессором.
- Во-первых, инструкция CMP вычитает второй операнд из первого и отбрасывает результат. Однако регистр FLAGS обновляется с результатами арифметической операции.
- Затем инструкция JG проверяет, установлен ли флаг GREATER в регистре FLAGS. Так как в нашем примере (напомним, что 1> 0), он выполняет скачок.
- Команда перехода изменяет счетчик программ (ПК), который является регистром, который контролирует, где ЦП будет читать следующую инструкцию.
- Затем CPU пытается прочитать следующую инструкцию. Поскольку мы прыгнули, следующая инструкция не та, которая сразу же после ранее обработанной.
Это обзор процесса. Если вы хотите получить более подробное объяснение, я рекомендую вам написать простую программу на языке С с инструкцией if, скомпилировать ее, разобрать (используя linux objdump
или эквивалент) и, возможно, прикрепить к нему отладчик и запустить его.
linux objdump
manual
Чтобы показать следующая команда должна быть выполнена в gdb
, используйте display/i $pc
Отличный вопрос! сложный ответ. Вам необходимо понять, как это происходит, чтобы понять его полностью, я рекомендую написать простой пример, скомпилировать его, связать с ним отладчиком и пройти через него по одной инструкции за раз. – Wug
@wug это отличная идея, спасибо. – Nealon