3

the following is the start of the code for the educational real mode x86 operating system MikeOs. (mikeos.sourceforge.net) As I understand it the x86 stack grows 'down' that is towards low memory, and the stack segment register ss points to the lowest possible memory location in the stack segment (offset 0). So, the question is, why is it necessary to add 4096bytes to the code segment in order to create a 4K stack? Should it not be sufficient to add 512 bytes to the code segment and store that in the ss stack segment, since the boot sector may only be 512 bytes long?

 BITS 16

 start:
  mov ax, 07C0h   ; Set up 4K stack space after this bootloader
  add ax, 288     ; (4096 + 512) / 16 bytes per paragraph
  mov ss, ax
  mov sp, 4096
  mov ax, 07C0h   ; Set data segment to where we're loaded
  mov ds, ax
  • You mean initializing `sp` to 0 and instead moving the stack segment further ahead? Consider what will happen when you try to push something onto the stack. Let's say you're pushing a word: `sp` is decremented by 2 and will wrap around to 0xFFFE. Let's say that `ss == 1`. The address that will be written to will be `(1 * 0x10) + 0xFFFE == 0x1000E`, _not_ `(1 * 0x10) - 2 == 0x0E`. – Michael Jul 01 '14 at 11:04
  • No I mean just doing mov ax, 07C0h add ax, 32 mov ss, ax mov sp, 4096. According to me, this would create a 4K stack just after the 512 byte boot sector. – user3793475 Jul 01 '14 at 12:03
  • 1
    Note - Microsoft's partition sector code for MSDOS and Windows 98 set all the segment registers to zero, and then sets SP to 7c00h (just below the loaded image). Then the code moves itself to 0000h:0600h, and branches to some offset from 0000h:0600h to continue. Once at 0000h:0600h, the code looks for a boot sector, loads it at 0000h:7c00h, and continues the process. This cycle could repeat again on a multi-boot system. – rcgldr Jul 01 '14 at 19:25

3 Answers3

2

Here is the memory map to make it easier to analyze:

-------------- <— 07C0:0 boot loader memory starts
|            |
| 512 bytes  |  For the boot loader code
--------------
|            |  It could be use for whatever purpose the author has planned
|            |  for this memory area.
| 4096 + 512 |  (Maybe for the OS? Or stage2 loader? Who knows, it doesn't matter.)
|            |
-------------- <- 19C0:0 - Stack Segment(SS):Stack Pointer(SP) - Max of the stack
|            |        /\
| 4KB stack  |        || Stack grows
--------------    19C0:1000                               - Start of the stack(bottom)
Wendell Tabat
  • 51
  • 1
  • 3
  • I had reviewed the code some time back under another answer, but the 4k below the stack appears to be used as a disk buffer. – Michael Petch Feb 12 '16 at 06:04
1

size of stack isn't related to size of code using stack. Example: a recursive piece of code can be a few dozens of bytes long, but use Megabytes of stack - though recursion in bootloaders isn't very likely. There are interrupts, though, and firmware in ROM, which may obtain control as result of some interrupts - not requiring a lot of stack but it adds to what bootloader already claims. In general, I'd say 512 bytes of stack are sufficient, but better be safe than sorry, especially if the cost of providing more stack space than that are zero.

Deleted User
  • 2,551
  • 1
  • 11
  • 18
0

You are right.

There is no reason for adding 4096 to ss. 512 is enought (just to move after code). Maybe the author reservers these 4k bytes for some data?

Michał Walenciak
  • 4,257
  • 4
  • 33
  • 61
  • Ok, that makes sense to me. But it is confusing that the author adds exactly 4K to the stack segment and also sets up a 4K stack. Maybe its just a coincidence. – user3793475 Jul 01 '14 at 12:10
  • Hard to say what is the real reason :). It's also common to have ss=cs if you know your code won't be big and you won't use too much stack ;) Also having ds,es,fs and gs = cs happens. It allows you to access any data from any segment using other segment register. – Michał Walenciak Jul 01 '14 at 12:40
  • @MichałWalenciak: That is actually the default if you used the tiny (com) memory model. For simple assembly programs, that reduces code complexity a lot. – PMF Jul 01 '14 at 19:26
  • 4k stacks are about the worst case scenario. `int 13h` on systems that support AHCI can use a good chunk of that 4k. The PCI BIOS spec says you need 1k for those calls. It has been a general rule of thumb that a 4k stack is sufficient in most situations. If you know you won't be making BIOS calls then you can live with much smaller stacks. As for the code the OP has, it is unclear why they offset the stack the way they did. – Michael Petch Oct 02 '15 at 07:17
  • Looking a bit more closely at the MikeOS code the extra 4k of memory between the boot loader and the top of the stack (lowest memory address of the stack) is used as a disk buffer. – Michael Petch Oct 03 '15 at 12:16