Я думаю, дело в том, где данные хранятся в программе, и поддержка ОС для информирования ЦПУ, является ли это кодом или данными.
Весь код размещен в другом сегменте изображения (вместе со статическими данными, такими как строки постоянных символов) по сравнению с хранилищем для переменных. ОС (и модуль управления памятью) должны это знать, потому что они могут выгружать код из памяти, просто отбрасывая его и перезагружая его из исходного файла на диске (по крайней мере, так делает Windows).
Итак, я думаю, что процессор «знает», является ли память данными или кодом. Несомненно, у современных конвейерных ЦП, которые у нас есть, также есть инструкции по-разному читать эту память, чтобы ЦП обрабатывал ее как можно быстрее (например, код может не кэшироваться, доступ к данным всегда будет осуществляться случайным образом, а не в потоке) *
По-прежнему возможно указывать счетчик вашей программы на данные, но ОС может сообщить ЦПУ об этом - см. Бит NX и настройки Windows "Защита выполнения данных" (панель управления системой)