I have many examples at http://github.com/dwelch67 for several different processors.
Each processor and sometimes subsets of a processor family have a different load pattern. usually one of these categories:
1) an address table for different types of interrupts / events (reset, interrupt, nmi, etc.), often called a vector table, this table is in a hard-coded location, the hardware power reads the address in reset, and then starts executing the code at the address, specified in the reset vector.
2) the instruction table, the addresses for these instructions are in a known place, for example, using ARM, this means that you receive one command per vector / event, so that one instruction must be loaded by a PC or branch (or subsequent vectors are not used, and you can use more instructions to exit the vector table.
3) let me think about some others
Some companies (processor architecture) use a high address, for example, 0xFFFE is a reset vector and 0xFFFC is an interrupt. msp430 and 6502, I think, like this. As you saw in the other answers, 8088/86 and the family use 0xFFFxxxFFFF0 as the entry / reset address.
Other people, such as ARM and Atmel AVR, use the 0x0000 address as an entry point.
If you go into your return trip machine when the processor memory interface is very simple, some bits of the address, bits of data, read and write gates and, possibly, chip selection or selection or something else. You would use external logic, parts of 74LSxx, for example, to decode some of the upper bits of the address, decode all zeros and all of them easily, so you would either have rum at the upper addresses (the upper bits of the address of all), or fall below the address (upper address bits of all zeros) or vice versa. Even today in microcontrollers and processors in general, this makes life easier. So your ARM and AVR will tend to assume that address 0 is rom, and ram is somewhere else. your x86 and msp430 and others will put the rom at the top and hurt below or somewhere in the middle.
Does this address need to be hard-coded in assembler? Well, not necessarily, usually you hard-code something for the linker to put the vectors in the right place, but there are assemblers that still support directives like .org, in which you specify the code after this directive is placed on this address into memory space.
Each processor has a kind of bootloader, even your computer. This is the only program that is compiled, knowing the processor load rule, which is the first bit of code that runs on this processor. From there it can change, you can only have one program, and you do not plan to change programs after downloading, sometimes it is simply called firmware. Now, sometimes the bootloader has some kind of hint, perhaps you are using a serial port and a mute terminal to enter commands or load a program using xmodem, etc. (Uboot, redboot, etc.). Often you want to boot and get up and work without human intervention, so it may be possible to press a key on the terminal / serial port or press a button on the board during boot, etc. Otherwise, the loader has a set of rules for what to do next, and these rules are unique to the author (s) of the loader, it is just software that you can do no matter what you want. For example, your computer, for example, this bootloader, is called the BIOS, and you can probably press F1 or F2 or DEL or another sequence of keys or keys and interrupt the normal boot process to do something else (change BIOS settings, etC) . Otherwise, the BIOS has a set of rules (sometimes / often that you can change) where it looks for the next thing to boot and run. Usually tries to find some media, such as a hard drive or a USB drive or a floppy disk or a CD / DVD containing the boot sector. This boot sector is just a code, the BIOS sets the rules about what this code should look like or what address, etc. It needs to compile, it loads this code, and then it is another form of bootloader that can do whatever it wants, boot Linux, boot windows, boot boards, ask a few questions about what you want to boot, run a memory testing program, anything.
Down the road, you can download another program, an operating system, one program that has its own rules that it follows, and if it decides to allow other programs to be downloaded, these programs must live by the rules. Sometimes, when you have mmu, you can make a program think that it works at one address when it really is on another, but it makes it so that you can make all programs assume that they work from a specific address, and then just compile them for that address (most programs you write for windows / linux etc.). but if you do not have mmu, then there may be different rules, such as the whole program should be position-independent code (without any hard-coded addresses), I was told that uclinux looks like this.
Microcontrollers are a good place to learn these kinds of things, since you may already have a bootloader (arduins come that way, lpc and st-chips often have a bootloader, a serial or USB drive, or both). Sometimes, like avr, the bootloader is in a state that you can change, separate the bootloader flash and the flash application, sometimes the bootloader is in the flash state, but only the chip manufacturer knows how to change / change it so that you get stuck with your bootloader forever. In any case, you can still create your own bootloader, which will run on top of this, where you can create a way to load other programs, the rules for these programs, to return to the bootloader, so that other programs can run, etc. I have an instruction (at different stages of debugging, the thumb has the ability to use it, like the one I played with someone else) so that you can wrap a dumb terminal and create your own environment without actually having to buy anything (you can do it with qemu and gdb, but not so simple).
If you look at these microcontrollers in particular, but this is a problem with all processors, as a rule, the boot code, including vectors, is in rom mode as soon as you start, although you do not always want these vectors to be hard-coded in rom , you either need to make some kind of circuitry that the rom code somehow branches onto something in ram, or there is a hardware circuitry where, after loading, you can flip the switch somewhere (write a bit to the byte somewhere in the register ) and change which memory is decoded at this address, at volyaya you switch to the ram and replace the vector table, with something soft. Some of these microcontrollers have some overly complex circuits for this. Here you should also look at the documents for this processor and / or chip to find out how it works. Sometimes this is something outside the chip on the board, which leads to a change in address space, so you should read about it.
Since most programmers at this level already know this, documents often do not go into details. They can simply indicate that the initial table of vectors begins here, but the elements or it can go through each element of the table, indicating the address, but can not indicate whether the contents of this table is an address in memory or an instruction that must be executed ... You should "just know." And how do you learn by asking others in the form of a look at other people's code.
variables and data are managed by you and the compiler. the language you use and the compiler you use will, for example, create segments .text, .data, .bss, and through the compiler or linker you must provide specific tool addresses where to place each of these things for this binary file. And in this deeply rooted case, this means that you go to the documents for the system (chip plus board) to find out where each part should be for the correct download and launch. And you must somehow put this information. if, for example, you write code that creates the .data segment (I usually donβt) and you boot from the flash, you should have some kind of circuit to compile the compiler, so the .data segment is in ram, but when you load its isnt in ram, you must have a copy of the .data segment somewhere in rum, then you must copy it to ram before you get into the main code of the code. Similarly, you need to set the stack pointers and, if necessary, change the vector table, etc. If you use a drum, you need to initialize the memory using code that can be run without memory to get the fraction, and then copy .data, zero.bss, set the stack pointer, then go to main ().