мой код C перевода к инструкциям для CPU корректен? - PullRequest
0 голосов
/ 05 сентября 2018

Для этого кода:

int main(void) {
  int a = 1;
  int b = 2;
  int* pa = &a;
  *pa = a + b;
  printf("%d", a);
}

Во время компиляции компилятор вычисляет, сколько места ему нужно. У нас есть 2 целых числа и один указатель. Так что это 2*4 + 8 = 16. Затем он указывает, где находится память данной переменной относительно адреса начальной точки. pa находится по адресу начальной точки и имеет длину 8 байтов. b находится по адресу начальной точки + 8 байтов и имеет длину 4 байта. a находится по адресу начальной точки + 12 байтов и имеет длину 4 байта.

Затем перейдите к инструкциям по времени выполнения:

  1. Попросить ОС выделить 16 байтов и предоставить адрес для этого пространства в памяти. Это будет адрес начальной точки.
  2. поместите двоичное представление 1 в местоположение a.
  3. поместите двоичное представление 2 в местоположение b.
  4. преобразовать относительный адрес a (адрес начальной точки + 12 байт) в его абсолютное местоположение и поместить его в местоположение pa.
  5. получить байты в местоположении a и байты в местоположении b, добавить их, а затем получить байты в местоположении pa. Используйте байты в местоположении pa в качестве адреса и поместите туда вычисленную сумму.
  6. печатать байты в местоположении a, преобразуя их сначала в десятичное число.
  7. освободите память и сообщите ОС, что программа завершена.

Это действительный перевод?

редактирование:

Давайте предположим, что используется супер простой компилятор (без оптимизации). Все, что его волнует, это правильное выполнение кода C.

Ответы [ 3 ]

0 голосов
/ 05 сентября 2018

Насколько я читаю, да, это правильный перевод. Нет, это почти 100%, конечно, не тот перевод, который собирается составить ваш компилятор. Стандарт C имеет так называемое правило как если бы , которое означает, что компилятор может создавать любую программу, побочные эффекты которой , как если бы программа была скомпилирована для так называемой абстрактной машины Си и беги туда.

На практике, например, компилятор может создать следующую программу:

  • поместите целое число '3' в регистр, который используется в качестве первого аргумента в вызовах функций
  • Звоните putchar
  • Обнулить регистр, который используется в качестве возвращаемого значения
  • возврат из main функции

Для наблюдателя побочные эффекты этой программы будут неотличимы от побочных эффектов вашей программы: она печатает 3 и возвращает от main с 0 в качестве возвращаемого значения.

0 голосов
/ 05 сентября 2018

Шаг 1 Переменные a, b и pa будут размещены в стеке. Следовательно, нет запроса к ОС на выделение памяти - вы просто будете использовать стек, который контролируется самим процессом. Возможно, он не будет запрашивать 16 байтов - достаточно 4 байта, поскольку вы эффективно используете переменную a. И даже этот является постоянным, поэтому экземпляры a можно заменить на 1.

Шаг 4: Этот шаг может быть полностью пропущен компилятором, поскольку вы не используете значение pa, пока оно не будет переназначено на следующем шаге.

Шаг 6: Вставить два аргумента (%d\0 строка и значение 1) в стек и вызвать функцию с именем printf. Не знаю, выводит ли он в терминал - может быть stdout перенаправляет в файл?

В конце концов, невозможно точно знать, какие инструкции будут получены из этого исходного кода. Зависит от архитектуры, версии операционной системы / ОС, версии компилятора / cc, флагов компилятора ...

0 голосов
/ 05 сентября 2018

Это в значительной степени один способ его перевода (a) , хотя локальные переменные функции обычно выделяются в стеке, а не запрашивают у ОС некоторое количество памяти для хранить их.

Конечно, с помощью умного компилятора в исходном коде достаточно информации, чтобы просто оптимизировать все до:

int main(void) { putchar('3'); }

(a) Стандарт ISO C не предписывает , как все делается под покровом, только в том, что он ведет себя определенным образом. Думайте о C как о виртуальной машине, которая реализует стандарт. То, как виртуальная машина делает это, на самом деле не имеет отношения к делу, и, конечно, не имеет никакого отношения к поведению.

...