Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The assembler is translating each line of your sorce code to processor instruction and generates these instructions in sequence, one after another, into the output binary file. Doing that, he maintains an internal counter which counts the current address of any such instruction, starting from 0 and upwards.</p> <p>If you're assembling a normal program, these instructions will end up in the code section at some object file with just blank slots for addresses, which have to be filled in with proper addresses by the linker afterwards, so it's not a problem.</p> <p>But when you assemble a flat binary file without any sections, relocations and other formatting, just raw machine instructions, then there is no information for the assembler about where are your labels indicating to and what are the addresses of your data. So, for example, when you have an instruction <code>mov si, someLabel</code>, then the assembler can only calculate the offset of this label starting from 0 at the beginning of the binary file. That is, it assumes that your code would be located in the memory beginning from the offset 0 in your code segment.</p> <p>If it's not true, and you want your machine instructions in memory to begin from some other address, eg. <code>7C00</code>, then you need to tell the assembler that the starting address of your program is <code>7C00</code> by writing <code>org 0x7C00</code> at the beginning of your source. This directive tells the assembler that it should start up its internal address counter from <code>7C00</code> instead of from <code>0</code>. The result is that all addresses used in such a program will be shifted by <code>7C00</code>. The assembler simply adds <code>7C00</code> to each of the address calculated for each label. The effect is as if the label was located in memory at the addres, say, <code>7C48</code> (<code>7C00 + 48</code>) instead of just <code>0048</code> (<code>0000 + 48</code>), no matter that it is offset only 48 bytes from the beginning of the binary image file (which, after loading at the offset <code>7C00</code> will give the proper address).</p> <p>As to your other question: <code>7C00</code> is the physical address of the bootloader. You can represent this physical address as a logical address (segment:offset) in a different ways, because segments overlap (next segment starts 16 bytes (<code>10</code> in hex) after the previous one). For example, you can use logical address <code>0000:7C00</code> which is the simplest configuration: you use segment <code>0</code> starting at the beginning of your RAM, and offset <code>7C00</code> from that <code>0</code>. Or, you can use logical address <code>07C0:0000</code>, which is <code>7C0</code>th segment. Remember that segments start 16 bytes apart from each other? So you simply multiply this <code>7C0</code> by <code>10</code> (<code>16</code> in decimal) and you get <code>7C00</code> -- see? It's a matter of shift one position to the right in your hexadecimal address! :-) Now you just add your offset, which is <code>0</code> this time, so it's still <code>7C00</code> physically. The byte <code>0</code> in segment <code>07C0</code> which starts at <code>7C00</code> in memory.</p> <p>Of course you can also use more complicated addresses, like, for example, <code>0234:58C0</code>, which means that the segment starts at <code>2340</code> and when you add <code>58C0</code> offset to it, you'll get <code>7C00</code> again :-) But doing that could be confusing. It all depends on what configuration you need. If you want to consider the <code>7C00</code> physical address as the start of your segment, just use segment <code>07C0</code> and your first instruction will be at offset <code>0</code>, so you don't need to put <code>org</code> directive, or you can put <code>org 0</code> then. But if you need to read/write some data below the <code>7C00</code> address (for example, peek the BIOS data or fiddle with interrupt vectors), then use segment <code>0</code> and offset <code>7C00</code> which means your first instruction (0th byte in your binary file) will be located at <code>7C00</code> physical address in memory; then you have to add <code>org 0x7C00</code> directive from the reasons described above.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload