O termo vem da linguagem assembly. Não consigo verificar a etimologia, mas acho que o nome vem do outro uso da seção. Enquanto a .dataseção indica variáveis que podem ser alteradas durante o curso da execução, a .textseção contém dados que não são alterados durante a execução, permitindo que sejam colocados na ROM, se necessário. Isso o torna útil para código, sim, mas também para seqüências de texto que não são alteradas. Provavelmente é daí que o termo veio.
Para abordar o comentário de Griffin sobre funções de primeira classe, considere o seguinte código python 3:
def counter():
x = 0
def increment(y):
nonlocal x
x += y
print(x)
return increment
O código que você realmente executa incrementacaba procurando internamente algo como:
self.func_dict['x'] += y
print(self.func_dict['x'])
Esse código executável pode ser colocado na ROM. Ele nunca muda durante a execução do programa, não importa quantas vezes você ligue counter(). O que muda é o selfponteiro e suas variáveis de membro. Aqueles devem ser colocados .data. Quando você return increment, na verdade, você está retornando uma nova instância de um objeto de função de incremento. Você não está criando dinamicamente novo código executável todas as vezes. O código em si é imutável, embora o ponteiro para ele não seja.
O único código que deve ser armazenado na .dataseção é o gerado por eval(), porque não é conhecido pelo compilador ou JIT no início do programa. No entanto, mesmo esse código é imutável. Se você alterar a string e ligar eval()novamente, não estará alterando o código da hora anterior eval(), mas criando um novo conjunto de códigos.
Embora o modelo de programação pareça que o código é mutável, o código real de modificação própria no nível de instrução do processador é perigoso e raramente encontrado fora dos tópicos do voodoo do SO, como a alternância de contexto do processo.
.texté uma diretiva de montagem. Assembly é texto.