I am following this hello-world boot sector program, which has the following linker script :
ENTRY(mystart)
SECTIONS
{
. = 0x7c00;
.text : {
entry.o(.text)
*(.text)
*(.data)
*(.rodata)
__bss_start = .;
*(.bss)
*(COMMON)
__bss_end = .;
}
.sig : AT(ADDR(.text) + 512 - 2)
{
SHORT(0xaa55);
}
/DISCARD/ : {
*(.eh_frame)
}
__stack_bottom = .;
. = . + 0x1000;
__stack_top = .;
}
Following is the entry.S
:
.code16
.text
.global mystart
mystart:
ljmp $0, $.setcs
.setcs:
xor %ax, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
mov $__stack_top, %esp
cld
call main
Following is the main
function
void main(void) {
int i;
char s[] = {'h', 'e', 'l', 'l', 'o', '', 'w', 'o', 'r', 'l', 'd'};
for (i = 0; i < sizeof(s); ++i) {
__asm__ (
"int $0x10" : : "a" ((0x0e << 8) | s[i])
);
}
while (1) {
__asm__ ("hlt");
};
}
I was expecting the __stack_top
to take the value of 0x8E00 (0x7C00 + 0x200 (512 bytes of boot sector) + 0x1000 (16 MB stack) ), but when I check the program in gdb, the instruction
mov $__stack_top, %esp
pushes 0x8c93 into %esp.
Why is this happening? Does eh_frame
impact in any way or am I missing something here? Please help.