Page 1 of 1

[C Kernel Development] Strange problem with arrays

Posted: Wed Jun 22, 2016 2:38 am
by EvolSoft
Hi all again :) ,
I'm Flavius12 (a member of EvolSoft) and I'm trying to write an alternative kernel in C using OpenWatcom C Compiler.
It's a day that I'm trying to fix a strange problem with arrays.
This is my code:

Code: Select all

void pokeb(int segment_, int offset_, char chr_);

void kernel(){
	char r[3] = {'T', 'K', 'S'};
	//Set 80x25 Text screen mode
	_asm {
		mov ah, 0
		mov al, 03h
		int 10h
	};
	//Put a byte into video memory (print a character on x=1 y=1)
	pokeb(0xB800, 0, r[1]);
	//Wait for key input
	_asm {
		xor ax, ax   
		int 16h
	};
}

void pokeb(int segment_, int offset_, char chr_){
	_asm {
		mov bx, segment_
		mov es, bx
		mov bx, offset_
		mov al, chr_
		mov BYTE PTR [es:bx], al
	};
}
This is the COMPILE.BAT file (used to compile the kernel):

Code: Select all

wcc -0 -d0 -ms -s -zl KERNEL.C
wlink FILE KERNEL.OBJ FORMAT RAW BIN NAME KERNEL.SYS OPTION NODEFAULTLIBS, START=kernel_
It's "booted" from the bootloader which prepares all registers before loading and executing it. This is what the bootloader does:
1. Read the kernel file and put it in 0x0060:0x0000
2. Set DS, ES and SS to 0x0060
3. Set SP to 0xFFFE
4. Jump to 0x0060:0x0000 (executes the kernel)
The problem is that when I try to print an element of the array it prints a wrong ASCII character. I don't understand why this happens only with arrays and not for example with a char pointer or with a single char. How can I fix this?

Thanks in advance,

Best Regards,

Flavius12 (EvolSoft)

Re: [C Kernel Development] Strange problem with arrays

Posted: Wed Jun 22, 2016 6:00 am
by Techel
It could be the inline assembly confusing the compiler, which assumes some registers not to change. Evaluate the ouput code.

Re: [C Kernel Development] Strange problem with arrays

Posted: Wed Jun 22, 2016 6:53 am
by EvolSoft
Techel wrote:It could be the inline assembly confusing the compiler, which assumes some registers not to change. Evaluate the ouput code.
I tried to remove inline asm but it doesn't work anyway.

Re: [C Kernel Development] Strange problem with arrays

Posted: Wed Jun 22, 2016 11:11 am
by EvolSoft
Don't worry. I solved the issue. It's a strange OpenWatcom bug maybe...

Re: [C Kernel Development] Strange problem with arrays

Posted: Wed Jun 22, 2016 12:13 pm
by BenLunt
If the boot loader code you talk above loads your code (starting with kernel()) to 0x00600 and then starts execution there, the

Code: Select all

//Set 80x25 Text screen mode
   _asm {
      mov ah, 0
      mov al, 03h
      int 10h
   };
is not the first set of instructions that get executed.

First, what if the compiler is placing all kinds of start up code before the kernel() function? This would be a very probable conclusion.

However, even if there is no start up code, and no prolog code to setup the stack, the "mov ah,0" is still not the first instruction being executed. The compiler has to create some form of code to place the 'TKS' on to the stack using

Code: Select all

char r[3] = {'T', 'K', 'S'};
I use a very well known and well used compiler to generate my kernel code. However, I have a loader file, written in assembly that sets up everything I need to allow the jump to straight C/C++ code that the compiler generates. Also, I have to instruct the compiler not to generate certain code, as well as I have to skip the first hundred bytes of the generated file since the compiler still generates a header.

I am not familiar with Watcom, does your compile.bat file account for this? Do the switches and parameters of the two lines account for this?
I would think not, since you give a "START=kernel_" parameter. The compiler/linker would create code to jump to that address, would it not?

In my opinion, you need to write a "pre-kernel" (if you will) file in assembly, setting up all of the items, stack, start address, etc. Then (pre/a)ppend it to your watcom generated file.

As the other comments suggest, dump the resultant KERNEL.SYS file and you will find that it does not indeed start with "mov ah,0".

One more thing, you need to send an attribute byte to the screen. The text mode screen memory at 0xB8000 has a 16-bit word for every character in the form of 0xAACC or (0xCC 0xAA). The 0xCC is the character byte, 'A' for example, while the 0xAA is the attribute byte, in the form of two 4-bit nibbles describing the foreground and background colors along with intensity/blink/etc (depending on the video setup).

Hope this helps.

Re: [C Kernel Development] Strange problem with arrays

Posted: Thu Jun 23, 2016 6:16 am
by EvolSoft
BenLunt wrote:If the boot loader code you talk above loads your code (starting with kernel()) to 0x00600 and then starts execution there, the

Code: Select all

//Set 80x25 Text screen mode
   _asm {
      mov ah, 0
      mov al, 03h
      int 10h
   };
is not the first set of instructions that get executed.

First, what if the compiler is placing all kinds of start up code before the kernel() function? This would be a very probable conclusion.

However, even if there is no start up code, and no prolog code to setup the stack, the "mov ah,0" is still not the first instruction being executed. The compiler has to create some form of code to place the 'TKS' on to the stack using

Code: Select all

char r[3] = {'T', 'K', 'S'};
I use a very well known and well used compiler to generate my kernel code. However, I have a loader file, written in assembly that sets up everything I need to allow the jump to straight C/C++ code that the compiler generates. Also, I have to instruct the compiler not to generate certain code, as well as I have to skip the first hundred bytes of the generated file since the compiler still generates a header.

I am not familiar with Watcom, does your compile.bat file account for this? Do the switches and parameters of the two lines account for this?
I would think not, since you give a "START=kernel_" parameter. The compiler/linker would create code to jump to that address, would it not?

In my opinion, you need to write a "pre-kernel" (if you will) file in assembly, setting up all of the items, stack, start address, etc. Then (pre/a)ppend it to your watcom generated file.

As the other comments suggest, dump the resultant KERNEL.SYS file and you will find that it does not indeed start with "mov ah,0".

One more thing, you need to send an attribute byte to the screen. The text mode screen memory at 0xB8000 has a 16-bit word for every character in the form of 0xAACC or (0xCC 0xAA). The 0xCC is the character byte, 'A' for example, while the 0xAA is the attribute byte, in the form of two 4-bit nibbles describing the foreground and background colors along with intensity/blink/etc (depending on the video setup).

Hope this helps.
Thanks for your reply. I'm still having the problem. I wrote a small assembly file which prepares the environment and the stack for the kernel and then calls it's main function (kernel_). The strange thing is that everything worked a bit when there was only KERNEL.C file.
Now I wrote a small BIOS level I/O code into the file CONIO.C and it's header CONIO.H and the problem got worse.
These are the commands executed to compile the kernel

Code: Select all

nasm -f obj -o AUTOLDR.OBJ AUTOLDR.ASM
wcc -0 -d0 -ml -s -zl KERNEL.C
wcc -0 -d0 -ml -s -zl CONIO.C
wlink FILE AUTOLDR.OBJ,KERNEL.OBJ,CONIO.OBJ FORMAT RAW BIN NAME KERNEL.SYS OPTION NODEFAULTLIBS,START=kernel_

Re: [C Kernel Development] Strange problem with arrays

Posted: Thu Jun 23, 2016 10:46 am
by BenLunt
The strange thing is that everything worked a bit when there was only KERNEL.C file.
Now I wrote a small BIOS level I/O code into the file CONIO.C and it's header CONIO.H and the problem got worse.
Most likely the compiler is placing the CONIO.C code before the kernel() code. However, without knowing anymore about Watcom and looking at your produced kernel.sys file, I couldn't tell you anymore.