I updated my boot disk that I made some time ago...It now supports a function call and a stack. The functionality I added is from any information I could find on Google so I can noway guarantee that this is the correct way to do this, all I know is that its works on my old PII computer....
assem code
.code16
.section .data
.section .text
.global _start
_start:
movw $0xb800, %ax
movw %ax, %es
movw $0x8000, %ax
movw %ax, %ss
movw $0xfffe, %sp
call tohere
loop1:
jmp loop1
tohere:
movb $0x47, %es:0
movb $0x1f, %es:1
movb $0x34, %es:2
movb $0x1f, %es:3
movb $0x31, %es:4
movb $0x1f, %es:5
movb $0x34, %es:6
movb $0x1f, %es:7
movb $0x33, %es:8
movb $0x1f, %es:9
movb $0x20, %es:10
movb $0x1f, %es:11
movb $0x48, %es:12
movb $0x1f, %es:13
movb $0x61, %es:14
movb $0x1f, %es:15
movb $0x63, %es:16
movb $0x1f, %es:17
movb $0x6b, %es:18
movb $0x1f, %es:19
movb $0x65, %es:20
movb $0x1f, %es:21
movb $0x72, %es:22
movb $0x1f, %es:23
movb $0x20, %es:24
movb $0x1f, %es:25
movb $0x46, %es:26
movb $0x1f, %es:27
movb $0x6f, %es:28
movb $0x1f, %es:29
movb $0x72, %es:30
movb $0x1f, %es:31
movb $0x75, %es:32
movb $0x1f, %es:33
movb $0x6d, %es:34
movb $0x1f, %es:35
movb $0x73, %es:36
movb $0x1f, %es:37
movb $0x20, %es:38
movb $0x1f, %es:39
ret
These are the lines that I set up my stack. I move 0x8000 hex into the ss segment register and initialize the stack pointer to 0xfffe. Like I said I'm not sure if this is correct all I know is it works on my old PII
movw $0x8000, %ax
movw %ax, %ss
movw $0xfffe, %sp
The code's in At&t syntax, sorry all I know. From this exe I stripped out the pertinent sections(everything but the header and footer) and did a little AWK magic and ended up with the hex array below
C code
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
char boot_buf[512] = {
0xB8,0x00,0xB8,0x8E,0xC0,0xB8,0x00,0x80,0x8E,0xD0,0xBC,0xFE,0xFF,0xE8,0x02,0x00,0xEB,0xFE,0x26,
0xC6,0x06,0x00,0x00,0x47,0x26,0xC6,0x06,0x01,0x00,0x1F,0x26,0xC6,0x06,0x02,0x00,0x34,0x26,0xC6,
0x06,0x03,0x00,0x1F,0x26,0xC6,0x06,0x04,0x00,0x31,0x26,0xC6,0x06,0x05,0x00,0x1F,0x26,0xC6,0x06,
0x06,0x00,0x34,0x26,0xC6,0x06,0x07,0x00,0x1F,0x26,0xC6,0x06,0x08,0x00,0x33,0x26,0xC6,0x06,0x09,
0x00,0x1F,0x26,0xC6,0x06,0x0A,0x00,0x20,0x26,0xC6,0x06,0x0B,0x00,0x1F,0x26,0xC6,0x06,0x0C,0x00,
0x48,0x26,0xC6,0x06,0x0D,0x00,0x1F,0x26,0xC6,0x06,0x0E,0x00,0x61,0x26,0xC6,0x06,0x0F,0x00,0x1F,
0x26,0xC6,0x06,0x10,0x00,0x63,0x26,0xC6,0x06,0x11,0x00,0x1F,0x26,0xC6,0x06,0x12,0x00,0x6B,0x26,
0xC6,0x06,0x13,0x00,0x1F,0x26,0xC6,0x06,0x14,0x00,0x65,0x26,0xC6,0x06,0x15,0x00,0x1F,0x26,0xC6,
0x06,0x16,0x00,0x72,0x26,0xC6,0x06,0x17,0x00,0x1F,0x26,0xC6,0x06,0x18,0x00,0x20,0x26,0xC6,0x06,
0x19,0x00,0x1F,0x26,0xC6,0x06,0x1A,0x00,0x46,0x26,0xC6,0x06,0x1B,0x00,0x1F,0x26,0xC6,0x06,0x1C,
0x00,0x6F,0x26,0xC6,0x06,0x1D,0x00,0x1F,0x26,0xC6,0x06,0x1E,0x00,0x72,0x26,0xC6,0x06,0x1F,0x00,
0x1F,0x26,0xC6,0x06,0x20,0x00,0x75,0x26,0xC6,0x06,0x21,0x00,0x1F,0x26,0xC6,0x06,0x22,0x00,0x6D,
0x26,0xC6,0x06,0x23,0x00,0x1F,0x26,0xC6,0x06,0x24,0x00,0x73,0x26,0xC6,0x06,0x25,0x00,0x1F,0x26,
0xC6,0x06,0x26,0x00,0x20,0x26,0xC6,0x06,0x27,0x00,0x1F,0xC3
};
int main(int argc, char**argv)
{
int floppy_desc;
boot_buf[510]=0x55;//to make the floppy/image bootable
boot_buf[511]=0xaa;//to make the floppy/image bootable
floppy_desc=open("/dev/fd0",O_RDWR);
lseek(floppy_desc,0,SEEK_CUR);
write(floppy_desc,boot_buf,512);
close(floppy_desc);
}
This will create a boot disk for a Intel machine that will create a stack and then call a function that will display some text and then loop forever...Note this program will only compile on a Linux box because of this line:
floppy_desc=open("/dev/fd0",O_RDWR);
If you plan to use this on a windows box you'll have to port it...
With this example you should be able to call anywhere within your code section letting the call/ret opcodes and the stack sweat the details...