babaliaris wrote:
From your answer I'm concluding to these hypotheses:
1) A segment does not only contain my code which in this examples is exactly 512 bytes. Until now I was thinking that this is true so I was expecting that the CS will point exactly at 0x7c .
yes -- a segment is the region of memory from segment.base to segment.base + segment.limit
in RMode, when you upadate a segment register, the segment.base field is filled in with the value: segment*16
in RMode, segment.limit is generally 64KB
so, when DS = 0, segment.base = 0, segment limit = 64KB, therefore segment region is the area of physical memory from 0 - 0xFFFF (inclusive) -- it is important to note that this area is the same size as what is addressable by a 16-bit offset (such as IP for code, or SP for the stack)
Quote:
2) When the program starts, IP happens to be exactly 0x7c, as the ORG offset, so that CS:IP = first instruction in my program.
not exactly -- the CS:IP combination equals 0x7C00, you don't know what CS is, and you don't know what IP is, you only know the result of CS.base + IP = 0x7C00
it is possible that CS = 0 and IP = 0x7C00 therefore CS:IP == 0*16+0x7C00 == 0x7C00
it is also possible that CS = 0x7C0 and IP = 0 therefore CS:IP = 0x7C0 * 0x10 + 0 == 0x7C00
other combinations are also possible, but are fairly rare
Quote:
3) When a jump is happening this is the way that IP is getting updated: IP = value_of(ORG) + label_offset, so CS:IP --> to the next instruction.
no
when a normal (immediate mode) jump happens, your assembler does this:
jump_operand = label_offset - current_offset
thus the instructions:
Code:
JMP .label
.label:
results in the assembler producing the code:
Code:
JMP 0
because there are exactly 0 bytes between the jump and the destination address
and the code
Code:
.label:
JMP .label
is turned into:
Code:
JMP -2
because the JMP short instruction is exactly 2 bytes long (so it is jumping backwards by 2 bytes to the beginning of the JMP instruction)
when the CPU executes the JMP instruction, it does this:
IP = IP + Jump_operand
Quote:
4) Data memory: DS + value_of(ORG) + label_offset .
almost -- it should be DS.base + value_of(ORG) + label_offset... but this is mixing 2 different steps
the assembler does
segment_offset = value_of(ORG) + label_offset
and the CPU itself does
DS.base + segment_offset
Quote:
But this still does not make sense. If DS = 0, like i set it in my program and ORG is the offset from the beggining of the code segment, then DS + value_of(ORG) + label_offset will probably give an address less than the beginning of the code segment itself, since DS is zero.
no it won't
DS = 0, therefore DS.base == 0
ORG is the address offset for where the file is located (in this case, it should be 0x7C00)
so the value the assembler calculates is this:
address = label_offset + 0x7C00
and then at runtime the CPU adds 0 (because DS.base == 0)
because the ORG is 0x7C00, the address will always be higher than 0x7C00 -- which is the address you are loading at
the important key is: DS.base + ORG should always equal the physical address where the file is being loaded into memory
in this case, since you are setting DS.base == 0, then ORG should be the address it is loaded to in memory (in this case, that is 0x7C00)