Можно воспользоваться формулой Вирта:
алгоритмы + структуры данных = программы. Строго говоря, структуры данных типа таблиц - не программы. Однако в общем случае нет признака, с помощью которого можно было бы отличить программу от данных. Пусть у CPU 256 инструкций, т.е. любое значение любого байта может быть воспринято как инструкция. Тогда любую случайную последовательность байтов можно интерпретировать и как программу, и как данные. Убедиться не сложно: возьмите картинку и замените расширение .jpg на .exe, попробуйте запустить на исполнение - ОС на компе добросовестно попытается выполнить, но сразу наткнется на нарушения в заголовке программы и будет ругаться. Однако мы же и не говорим, что любая программа должна быть корректной.
При этом утверждение
"любую случайную последовательность байтов можно интерпретировать и как программу" стоит слегка подкорректировать, т.к. некоторые инструкции требуют операндов (аргументов) за ними, и если последовательность обрывается на такой инструкции, получится программа без обязательных конечных элементов. Это затруднение в нашем умозрительном примере можно легко преодолеть правилом, что если операндов нет, то определены какие-то по умолчанию.
С точки зрения системного программирования факт, что любой файл можно рассматривать и как программу, и как данные очень важен: и программы, и данные мы копируем, удаляем, сравниваем с помощью одних и тех же утилит. Мы так к этому привыкли, что не задумываемся о столь значительном достижении, сделанном в ходе развития компьютинга