ARM microcontrollers, the newer Cortex-M ones, have modes to operate either from RAM or ROM. Check, for example, BOOT0 and BOOT1 bits in STM32's Reference Manual. This pretty much configures the start address of execution by actually aliasing the actual memory addresses into a fixed memory address segment (0x0000 0000
to 0x0007 FFFF
).
The Cortex-M core has four types of "memory": RAM, ROM (flash and System Memory), FSMC and peripheral. RAM is, well, internal static RAM. ROM is internal flash or the unwritable embedded bootloader. FSMC allows using external memory (both RAM and ROM, depending what the external hardware is). Peripheral memory are specific registers that map to peripheral functions, like UARTs, ADCs, etc. The hardware to access them is separate to gain speed (Harvard-style), specially because flash is slower than SRAM.
Yet, all of those are unified in a single address space (Von Neumann-style), which makes access to them simplified from a programmer's perspective. They differ only by their address ranges (implementation-dependent). The BOOT pins allow configuration between three start addresses: one in RAM, one in ROM (read-only bootloader) and another one in ROM (flash). This makes it possible to answer your question as "both". I never tried, but it appears to be possible to jump from one segment to another.
Keep in mind, however, that those memories still cannot be dealt with equally. You can't arbitrarily write to ROM. It's flash, making them rewritable, but you must use a special procedure to write to them (it's usually called something like "using flash as EEPROM" to store program data, or "bootloader" when storing program code, usually at startup).
Curious info:
When one executes from flash (ROM), the instructions are retrieved directly from ROM. There's usually some startup code that copies data from ROM to RAM (initialized global variables, usually stored in the data section). The Reference Manual also carries this info
When booting from SRAM, in the application initialization code, you
have to relocate the vector table in SRAM using the NVIC exception
table and offset register.
which is usually carried out by the startup code.