Xsi
Xsi

Reputation: 201

Given MBR assembly code, how stack works? Couple of questions on MBR

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

Answers (2)

Brendan
Brendan

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

Michael
Michael

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

Related Questions