Only absolute addressing mode was available and all others were achieved by self-modifying code.
This scheme allows for a degree of self-modifying code and requires metaprogramming language features.
In the early days of computers, self-modifying code was often used to reduce use of limited memory, or improve performance, or both.
Some very limited instruction sets leave no option but to use self-modifying code to perform certain functions.
In some cases short sections of self-modifying code execute more slowly on modern processors.
However, this is like writing self-modifying code, which indeed was done in the early days of programming but was quickly dismissed as a generally bad idea.
If the text section is not read-only, then the particular architecture allows self-modifying code.
Indeed, a slightly cryptic but essentially simple idiom allows this to be done by the program itself as it is running, producing self-modifying code.
Another example is self-modifying code, which allows a program to modify itself.
All variables can be changed at run-time, allowing for self-modifying code.