Page 1 of 1
Memory Access in Protected Mode
Posted: Thu May 29, 2008 8:58 am
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'
Posted: Thu May 29, 2008 9:55 am
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
Posted: Thu May 29, 2008 9:58 am
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
Posted: Thu May 29, 2008 10:28 am
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.
Posted: Thu May 29, 2008 11:02 am
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.
Posted: Thu May 29, 2008 1:16 pm
by Spike7d8
Thanks Combuster! It now works