I am writing a very simple boot and kernel in asm and c++. The thing is my development system is windows and I cannot use cpu interupts on windows, or can I?

I dont think that my newly created kernel will be able to understand invoke ConsoleA or an of those win32 api calls. So what are my alternatives?

Recommended Answers

All 14 Replies

I cannot use cpu interupts on windows, or can I?

Whether or not you can use CPU interrupts under Windows depends on your version of Windows. XP has a 16-bit virtual machine thingy built in to support (most) old DOS and W95 programs, IIRC.

I dont think that my newly created kernel will be able to understand invoke ConsoleA or an of those win32 api calls.

Of course your kernel won't be able to use OS-specific calls; they're part of the OS that isn't loaded when your OS is.

So what are my alternatives?
You could use CPU interrupts, write your own code to handle things that interrupts don't.

Does that answer your question? :)

I have windows 7, and as far as I know, no interrupts are supported on windows 7.

There'll be at least the 'DOS' interrupt - int 0x21. Why do you need interrupts on Windows if you're making an OS anyway?

There are some axample code that uses interrupt to call the print from the cpu.

Is the code intended to run at the Application Level, or as an OS in itself?

The code is the kernel itself, the kernel is 512 bytes so its basicly just my bootloader:

Here is my code:

mov ax, 0x07C0  ; set up segments
   mov ds, ax
   mov es, ax

   mov si, welcome
   call print_string

 mainloop:
   mov si, prompt
   call print_string

   mov di, buffer
   call get_string

   mov si, buffer
   cmp byte [si], 0  ; blank line?
   je mainloop       ; yes, ignore it

   mov si, buffer
   mov di, cmd_hi  ; "hi" command
   call strcmp
   jc .helloworld

   mov si, buffer
   mov di, cmd_help  ; "help" command
   call strcmp
   jc .help

   mov si,badcommand
   call print_string 
   jmp mainloop  

 .helloworld:
   mov si, msg_helloworld
   call print_string

   jmp mainloop

 .help:
   mov si, msg_help
   call print_string

   jmp mainloop

 welcome db 'Welcome to My OS!', 0x0D, 0x0A, 0
 msg_helloworld db 'Hello OSDev World!', 0x0D, 0x0A, 0
 badcommand db 'Bad command entered.', 0x0D, 0x0A, 0
 prompt db '>', 0
 cmd_hi db 'hi', 0
 cmd_help db 'help', 0
 msg_help db 'My OS: Commands: hi, help', 0x0D, 0x0A, 0
 buffer times 64 db 0

 ; ================
 ; calls start here
 ; ================

 print_string:
   lodsb        ; grab a byte from SI

   or al, al  ; logical or AL by itself
   jz .done   ; if the result is zero, get out

   mov ah, 0x0E
   int 0x10      ; otherwise, print out the character!

   jmp print_string

 .done:
   ret

 get_string:
   xor cl, cl

 .loop:
   mov ah, 0
   int 0x16   ; wait for keypress

   cmp al, 0x08    ; backspace pressed?
   je .backspace   ; yes, handle it

   cmp al, 0x0D  ; enter pressed?
   je .done      ; yes, we're done

   cmp cl, 0x3F  ; 63 chars inputted?
   je .loop      ; yes, only let in backspace and enter

   mov ah, 0x0E
   int 0x10      ; print out character

   stosb  ; put character in buffer
   inc cl
   jmp .loop

 .backspace:
   cmp cl, 0    ; beginning of string?
   je .loop ; yes, ignore the key

   dec di
   mov byte [di], 0 ; delete character
   dec cl       ; decrement counter as well

   mov ah, 0x0E
   mov al, 0x08
   int 10h      ; backspace on the screen

   mov al, ' '
   int 10h      ; blank character out

   mov al, 0x08
   int 10h      ; backspace again

   jmp .loop    ; go to the main loop

 .done:
   mov al, 0    ; null terminator
   stosb

   mov ah, 0x0E
   mov al, 0x0D
   int 0x10
   mov al, 0x0A
   int 0x10     ; newline

   ret

 strcmp:
 .loop:
   mov al, [si]   ; grab a byte from SI
   mov bl, [di]   ; grab a byte from DI
   cmp al, bl     ; are they equal?
   jne .notequal  ; nope, we're done.

   cmp al, 0  ; are both bytes (they were equal before) null?
   je .done   ; yes, we're done.

   inc di     ; increment DI
   inc si     ; increment SI
   jmp .loop  ; loop!

 .notequal:
   clc  ; not equal, clear the carry flag
   ret

 .done:     
   stc  ; equal, set the carry flag
   ret

   times 510-($-$$) db 0
   dw 0AA55h ; some BIOSes require this signature

It uses a few interrupts.

Okay, nice code - looks good. But I still don't get why you wanted to know whether low-level ints work under Windows.. What relevance is there?

I just wanted to code in asm an was frustrated that I have to use C calls and cannot write my own code without using win32 api or some other api. I was wondering if I can (some way) use int like i would in linux.

Right.. because your above code is an operating system in its own right, and cannot use C calls or Windows/Linux Interrupts. Now you say that you want to use Windows Interrupts... I'm confused. Are you writing an Operating System in its own right, or an application to run under Windows?

Interrupts occur whenever a piece of hardware needs attention, or the processor detects an error condition. There are also software interrupts which are mostly just a matter of convenience, and provide a means of indirect addressing.

Operating systems will mostly not allow applications to issue software interrupts, because they could take them directly into the heart of the kernel, where they have no business being. The only exceptions might be the odd one or two, which are made so that applications can make system calls.

I dont think that my newly created kernel will be able to understand invoke ConsoleA or an of those win32 api calls. So what are my alternatives?

The alternative is to write your own system calls. Operating systems are there to provide services to applications programs. They themselves directly program the hardware.

Accessing Windows functions from ASM is fairly difficult. But if I get you right, that's not what you want.
Interrupts are also not accessible when having an OS running between your software and the CPU.
If you intent to write your own interrupt-handler, you can test it with an emulator. I use qemu for that. It's a very simple programme, but therefor (IMO) the best thing to examine your code.

I think what you are missing is that you need a cross compiler. You can't use your masm assembler which was written for MS-DOS operating system to compile your own operating system because masm will expect you to use MS-DOS interrupts. Since you are writing your own os then you also need to implement your own hardware interrupts for the hardware you want to support. Just pretend MS-Wihdows and MS-DOS do not exist when you work on your program.

You can use a virtual machine and build your OS in that, including using interrupts. In any case, this is not a simple subject, and from your posting you have a lot of studying to do before you start exploring the joys of interrupt tables, jump vectors, interrupt masking, non-maskable interrupts, and all that stuff.

That aside, interrups are generally of two sorts - hardware interrups and software interrups. Hardware interrups are to deal with hardware events, such as data arriving at a port, a keyboard key is pressed, a clock tick has happened (context switch time), etc. Software interrupts are just as they sound, interrupts that allows software to do stuff "out-of-band". An example of this could be the cron task that runs on most systems to run specific programs at specific times.

Questions about OS development are a bit outside the usual range for this forum; you might want to try the OS Dev forums at OSDev.org, as they are experts in the subject. Note that you need to tread lightly there, as they are rather rough with newcomers and do not suffer fools gladly. Still, the Wiki there has answers to many of the questions you are likely to have.

As for your specific question, the real issue is this: even if you are running this on a Windows development platform, your are presumably running it with an emulator such as Bochs, or through a virtual machine client such as Virtual PC or VMWare. In either case, the emulator/VM will behave as if it were running on bare metal; as far as your code is concerned, there won't be any Windows system to call out to. Thus, any handling of system services will have to come from you and you alone, or from the hardware BIOS (which will only help in a 16-bit system and is of minimal value anyway).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.