Reputation: 201
What means this segment:
MOV SI,SP
PUSH AX
POP ES
How does ES get 0000:7c00 (and further DS)
In this MBR model?
0000:7C00 FA CLI disable int's
0000:7C01 33C0 XOR AX,AX set stack seg to 0000
0000:7C03 8ED0 MOV SS,AX
0000:7C05 BC007C MOV SP,7C00 set stack ptr to 7c00
0000:7C08 8BF4 MOV SI,SP SI now 7c00
0000:7C0A 50 PUSH AX
0000:7C0B 07 POP ES ES now 0000:7c00
0000:7C0C 50 PUSH AX
0000:7C0D 1F POP DS DS now 0000:7c00
0000:7C0E FB STI allow int's
0000:7C0F FC CLD clear direction
0000:7C10 BF0006 MOV DI,0600 DI now 0600
I released that it's like some special case (or undocumented procedure) - before and after interruption CLI / STI , is blocked.
/upd source added: http://www.nondot.org/sabre/os/files/Booting/mbr.txt
Upvotes: 1
Views: 387
Reputation: 37232
Here's my interpretation of the code:
0000:7C00 FA CLI disable int's
0000:7C01 33C0 XOR AX,AX AX = 0x0000
0000:7C03 8ED0 MOV SS,AX SS = 0x0000
0000:7C05 BC007C MOV SP,7C00 SS:SP = 0x0000:0x7C00
0000:7C08 8BF4 MOV SI,SP SI = 0x7C00
0000:7C0A 50 PUSH AX
0000:7C0B 07 POP ES ES = 0x0000
0000:7C0C 50 PUSH AX
0000:7C0D 1F POP DS DS = 0x0000
0000:7C0E FB STI allow int's
0000:7C0F FC CLD clear direction
0000:7C10 BF0006 MOV DI,0600 DI = 0x0600
MOV CX,0100 CX = 0x0100
REP MOVSW Copy 256 words (512 bytes)
from 0x0000:0x7C00 to
0x0000:0x0600
JMP ?? Jump to relocated code
I made up the last 3 instructions; but I can almost guarantee this is what the actual MBR does. The reason for this is that the MBR normally loads an OS's boot sector at 0x7C00 and can't overwrite itself, and therefore has to relocate itself first.
I don't know why they didn't use MOV ES,AX
and MOV DS,AX
instead of push/pop. Both versions cost 2 bytes though (e.g. 2 bytes for MOV ES,AX
vs. one byte for PUSH AX
plus another byte for POP ES
) so the difference is irrelevant (code size is the most important thing when you've only got 512 bytes to use and 66 of them must be partition table and magic signature at the end).
Upvotes: 1
Reputation: 58447
ES
by itself does not point at 0000:7c00, since ES is 16-bit. What those comments should say is that DS:SI
and ES:SI
both point at 0000:7c00.
This is because DS
and ES
are both set to 0 by pushing AX
(which contains 0 at that point), and then popping the segment register. Since SI
is given the value 7c00 you'll have both DS:SI
and ES:SI
pointing at 0000:7c00 (the absolute address in real mode is segment * 0x10 + offset
).
Upvotes: 1