Процессор делает только то, что вы говорите. Как вы заметили, процессор не может определить разницу между «данными» и «кодом» в памяти: это всего лишь последовательность байтов. То, что вы говорите, делает с этими байтами, определяет, как оно обрабатывается.
Когда программа компилируется, в сгенерированном исполняемом файле содержится информация о том, какие части являются кодом, а какие - данными. Когда программа выполняется, операционная система загружает код и данные в разные части памяти, а затем сообщает процессору начать выполнение кода в точке входа программы. Оттуда процессор выбирает первую инструкцию, выполняет ее и переходит к следующей инструкции.
Это все очень упрощенно, конечно, но я думаю, вы поняли идею.
В более старых процессорах и старых операционных системах ничто не мешает вам заставить процессор начинать выполнять инструкции, которые находятся в середине сегмента данных. Или, на самом деле, от модификации «данных» в середине сегмента кода - тем самым создавая самоизменяющийся код. Более новые процессоры и операционные системы обычно имеют некоторую форму предотвращения выполнения данных и блокируют, чтобы предотвратить изменение кода. В противном случае самоизменяющийся код может стать серьезной угрозой безопасности.
Краткий ответ: процессор обрабатывает код как код, потому что вы говорите ему. Иначе, все просто байты в памяти.