Page 1 of 1

Stupid arrays in C

Posted: Sat Feb 16, 2008 8:15 pm
by hanswurst
Hi,

after pausing os development a few years i just tried to come back.

I wrote a very small piece of code th have an environment to start with, but it drives me crazy. Grub is booting my elf32 file containing this piece of code:

Code: Select all

void print()
{
	volatile char *videoMem = (volatile char*)0xB8000;
	videoMem[0]='A'; //prints an A to (0,0) on the screen
	videoMem[1]='B'; //overwrites the A with a B
	videoMem[2]='C'; //makes the B cyan on red
	videoMem[3]='D';//writes a D to (1,0)
}
Somehow the first and the second element of an array are always the same. However, increasing the pointer (with videoMem++) works correctly. Even the assemler code gcc -S creates seems to be correct:

Code: Select all

        movq    $753664, -8(%rbp)
        movq    -8(%rbp), %rax
        movb    $65, (%rax)
        movq    -8(%rbp), %rax
        incq    %rax
        movb    $66, (%rax)
        movq    -8(%rbp), %rax
        addq    $2, %rax
        movb    $67, (%rax)
        movq    -8(%rbp), %rax
        addq    $3, %rax
        movb    $68, (%rax)
Am I stupid, or is this a bug in my (emulated) hardware?

Cheers, Michael

Posted: Sat Feb 16, 2008 8:21 pm
by t0xic
IIRC, you need to write the character and then the attribute, or both as a word. i.e.

Code: Select all

video[0] = 'A';
video[1] = 0x7; // gray
--Michael[/code]

Posted: Sat Feb 16, 2008 8:34 pm
by hanswurst
t0xic wrote:

Code: Select all

video[0] = 'A';
video[1] = 0x7; // gray
Right, that should result in a grey A, but it results in a point (ASCII character 7) being shown (like I had written 0x7 directly to video[0]) on my machine.

Posted: Sat Feb 16, 2008 8:47 pm
by t0xic
Have you tried without the volatile keyword? I don't think that would make a difference, but it's worth a shot

Re: Stupid arrays in C

Posted: Sat Feb 16, 2008 8:53 pm
by binutils
hanswurst wrote:

Code: Select all

void print()
{
	volatile char *videoMem = (volatile char*)0xB8000;
	videoMem[0]='A'; //prints an A to (0,0) on the screen
	videoMem[1]='B'; //overwrites the A with a B
	videoMem[2]='C'; //makes the B cyan on red
	videoMem[3]='D';//writes a D to (1,0)
}
instead try this, not sure work but let me know
void print()
{
volatile unsigned char *videoMem = (volatile unsigned char*)0xB8000;
videoMem[0]='A'; //prints an A to (0,0) on the screen
videoMem[1]='B'; //overwrites the A with a B
videoMem[2]='C'; //makes the B cyan on red
videoMem[3]='D';//writes a D to (1,0)
}

Posted: Sat Feb 16, 2008 9:31 pm
by pcmattman
Endianess mistake?

Code: Select all

video[1] = 'A';
video[0] = 0x7; // gray

Posted: Sat Feb 16, 2008 10:08 pm
by os.hacker64
isn't video[0] before [1]? thats why your getting the char 7.

Posted: Sat Feb 16, 2008 10:45 pm
by iammisc
Is your stack set up right?

Just a thought but I've found that a lot of times with os coding, things just seem to point to the exact place you don't want them to.

Posted: Sat Feb 16, 2008 10:59 pm
by nick8325
You said your program is elf32, but that assembly code is 64-bit. Try passing -m32 to gcc to make it emit 32-bit code. (x86-64's instruction set is very similar to x86's, but not the same, which could make your program sort-of-but-not-quite-work.)

Posted: Sun Feb 17, 2008 4:02 am
by hanswurst
nick8325 wrote:You said your program is elf32, but that assembly code is 64-bit. Try passing -m32 to gcc to make it emit 32-bit code. (x86-64's instruction set is very similar to x86's, but not the same, which could make your program sort-of-but-not-quite-work.)
Yes, that was it. I should have seen it myself. ](*,)
Thanks to all of you for the support.

Cheers, Michael

Posted: Sun Feb 17, 2008 5:26 am
by binutils
when grub 0.97 compiled fine with pure-64 gcc(so far), then that will be easier development.