Memory Access in Protected Mode

Programming, for all ages and all languages.
Post Reply
Spike7d8
Posts: 3
Joined: Thu May 29, 2008 8:38 am

Memory Access in Protected Mode

Post by Spike7d8 »

I am trying to read from the memory in protected mode, but it does not work. Curious enough, I can write to the memory.

The code is extremely simple, so I am asking for your help. The problem is at line 27. The programs displays an X if line 28 is uncommented.

Code: Select all

	mov eax, [ds:video]
	;mov eax, 0B8000h
	mov byte [ds:eax], 'X'
Attachments
boot.asm
(1.34 KiB) Downloaded 66 times
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

I think the problem is that 'video' is declared as a word, which is not long enough to hold the value 0xB8000. 'video' needs to be declared as dd, not dw.

Out of interest, why are you using the segment overrides? DS should be used by default with a MOV instruction.

Cheers,
Adam
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

One other thing - despite the fact that you are using the wrong size variable declaration, if the situation ever does arise where you are doing this again, use:

Code: Select all

mov eax, WORD[variablename]
or
mov ax, [variablename]
when you are loading a 32 bit register with a 16 bit value. I think this is better codeing practice.

Also - didn't your assembler give you a compile warning about trying to store 0xB8000 in a 16 bit variable?

Cheers,
Adam
Spike7d8
Posts: 3
Joined: Thu May 29, 2008 8:38 am

Post by Spike7d8 »

Thanks for the reply!

Indeed, dd solved the problem (I began writing 32-bit assembly just a few days ago). I used segment overrides because I was becoming paranoid :(.

Unfortunately, the main problem with the memory access is with the C language. At this point, local variables work, but global ones don't.

I have attached the code that enables a20, enters protected mode (just like in the previous boot.asm) and also loads the C program.

The C code: (if the video pointer is declared locally the program works)

Code: Select all

char *video = (char *)0xB8000;

void kmain ()
{
	video[0] = 'C';
	asm("hlt");
}
And it's disassembly:

Code: Select all

00000000  55                push ebp
00000001  89E5              mov ebp,esp
00000003  A110000000        mov eax,[0x10]
00000008  C60043            mov byte [eax],0x43
0000000B  F4                hlt
0000000C  5D                pop ebp
0000000D  C3                ret
0000000E  90                nop
0000000F  90                nop
00000010  00800B000000      add [eax+0xb],al
00000016  0000              add [eax],al
00000018  0000              add [eax],al
0000001A  0000              add [eax],al
0000001C  0000              add [eax],al
0000001E  0000              add [eax],al
This might be again a beginners question, but I cannot do anything without global variables and I don't want to program everything in asm. If someone spots the problem, please tell me.
Attachments
boot.asm
(1.75 KiB) Downloaded 32 times
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

This is obviously a linker problem - Your code tries to access data somewhere in the IVT (0x10), where it should probably near the end of your kernel (0x100010).

You should at least use a linker script. You can find one in the Bare bones tutorial - in fact, its a good excercise to run through it completely.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Spike7d8
Posts: 3
Joined: Thu May 29, 2008 8:38 am

Post by Spike7d8 »

Thanks Combuster! It now works :)
Post Reply