MOV AX, 0x0000 doesn't work.
Re: MOV AX, 0x0000 doesn't work.
If the proper section loading above is used (the third code I posted rather than the second), then /ALIGN:512 isn't needed. This is better because you don't risk storing the uninitialized part of a section. The /FILEALIGN:1 option helps further reducing file size by eliminating all padding in the file.
- RGOS
- Member
- Posts: 38
- Joined: Sat Feb 13, 2010 10:52 am
- Location: Buurmalsen, The Netherlands
- Contact:
Re: MOV AX, 0x0000 doesn't work.
Hello,
Thanks.
I finaly found it (I used tab instead of space (stupid that I didn't think of that)), but that sequence is in the code of MEMEM, but that is now commented out (it isn't going to work because its part 16 bit code and part interrupts that aren't available in RMode (I've to find a way to correct this)).Combuster wrote:You are, once again, executing garbage. Actually, it looks like you're halfway some other (16-bits?) instructions, since that opcode contains mov ax, 0x1000; push ax; mov di, ax; - try if you can find that sequence somewheresar byte ptr ds:[eax+0x89501000], 0xc7
Thanks.
Program development: Think, think more and think again, then find the solution and code it.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
- RGOS
- Member
- Posts: 38
- Joined: Sat Feb 13, 2010 10:52 am
- Location: Buurmalsen, The Netherlands
- Contact:
Re: MOV AX, 0x0000 doesn't work.
Hello,
I've changed alot since a time ago (I've changed some colors, and added a bootmenu (just press enter because 32 bits is already selected)) so I post the new floppy image with this post.
Also I've tried Gigasoft's third code, but now I run into trouble, because the instruiction 'rep stosb' gives me a 'Virtual machine kernel stack fault (hardware reset)' error in VMWare, and a reset in Bochs. And I have, at the moment, no clou how this is happening, do anyone of you know it? I have to go and get some sleep now, the Bochs log will be posted tomorrow.
Thanks.
I've changed alot since a time ago (I've changed some colors, and added a bootmenu (just press enter because 32 bits is already selected)) so I post the new floppy image with this post.
Also I've tried Gigasoft's third code, but now I run into trouble, because the instruiction 'rep stosb' gives me a 'Virtual machine kernel stack fault (hardware reset)' error in VMWare, and a reset in Bochs. And I have, at the moment, no clou how this is happening, do anyone of you know it? I have to go and get some sleep now, the Bochs log will be posted tomorrow.
Thanks.
- Attachments
-
- floppyimg.rar
- The newest floppy image.
- (11.61 KiB) Downloaded 124 times
Program development: Think, think more and think again, then find the solution and code it.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
Re: MOV AX, 0x0000 doesn't work.
The file isn't loaded correctly because you both add 32 to ES and 512 to BX. You should remove the instruction that adds the sector size to BX.
It also turns out that the KERNEL.EXE has sections with VirtualSize less than SizeOfRawData. I didn't account for this in my code, so my Sectionloop code should be changed to:
Here are some other issues I could find:
In the boot sector
DL is stored to two variables before loading DS, overwriting the keyboard IRQ vector instead of the variable it should store to. It should only store the value after loading DS.
There is no need to have a CLI before loading the segment registers. When loading SS, interrupts are automatically disabled during the next instruction.
There is no need to load FS and GS, since you don't use them.
There's an unused string: "OK" and an unused function which prints it.
The boot sector jumps to 0x28:0x280. If you change it to 0:0x500, you don't need a far jump in the beginning of kernel.sys.
In KERNEL.SYS
There's still an unnecessary mov ax,0 where AX is already 0.
Puts16 is inlined twice where you could just have called it instead.
The functions that display "16 bits", "32 bits" and "64 bits" are very repetitive and could have been implemented with a loop, like this:
When pressing the Up key, there are unnecessary instructions when moving the maximum choice into the current choice.
After pressing Enter, after the second int 0x10, there are also instructions which don't do anything useful. The first value popped is always 0, since it's set by the push ax at the start, where AX is 0. Then, the current choice is loaded into both AL and AH and checked twice. The 0 that was popped is pushed again, and then popped and not used.
The MEMEM function stores the return address in a byte variable. It should be a dword.
After calling LoadFile, the number of clusters is stored as a ImageSize, which is also a byte variable and should be a dword.
In KERNEL.EXE
I forgot to mention that you should turn off Incremental Linking under Configuration Properties => Linker.
The functions strcmp, strlen, strcpy and memset have to be linked in statically, so go to Configuration Properties => C++ => Code Generation and set Runtime Library to just Multi-threaded (not DLL or Debug), or implement these four functions by yourself.
It also turns out that the KERNEL.EXE has sections with VirtualSize less than SizeOfRawData. I didn't account for this in my code, so my Sectionloop code should be changed to:
Code: Select all
sectionloop:
mov ebp,[esi+ebx]
mov edi,[esi+ebx+4]
add edi,IMAGE_PMODE_BASE
mov ecx,[esi+ebx+8]
cmp ecx,ebp
jb vsize_ok
mov ecx,ebp
vsize_ok:
sub ebp,ecx
push esi
add esi,[esi+ebx+12]
rep movsb
pop esi
mov ecx,ebp
mov al,0
rep stosb
add ebx,40
dec edx
jnz sectionloop
In the boot sector
DL is stored to two variables before loading DS, overwriting the keyboard IRQ vector instead of the variable it should store to. It should only store the value after loading DS.
There is no need to have a CLI before loading the segment registers. When loading SS, interrupts are automatically disabled during the next instruction.
There is no need to load FS and GS, since you don't use them.
There's an unused string: "OK" and an unused function which prints it.
The boot sector jumps to 0x28:0x280. If you change it to 0:0x500, you don't need a far jump in the beginning of kernel.sys.
In KERNEL.SYS
There's still an unnecessary mov ax,0 where AX is already 0.
Puts16 is inlined twice where you could just have called it instead.
The functions that display "16 bits", "32 bits" and "64 bits" are very repetitive and could have been implemented with a loop, like this:
Code: Select all
Display16Bits:
mov si,str_16
mov di,324
jmp DisplayBits
Display16Bits:
mov si,str_32
mov di,484
jmp DisplayBits
Display16Bits:
mov si,str_64
mov di,644
DisplayBits:
call DisplayColoredString
mov si,str_bits
DisplayColoredString:
push es
mov es,0xb800
dcs_loop:
lodsb
test al,al
jz dcs_end
stosb
mov al,bl
stosb
jmp dcs_loop
dsc_end:
pop es
ret
str_16 db "16",0
str_32 db "32",0
str_64 db "64",0
str_bits db " bits",0
After pressing Enter, after the second int 0x10, there are also instructions which don't do anything useful. The first value popped is always 0, since it's set by the push ax at the start, where AX is 0. Then, the current choice is loaded into both AL and AH and checked twice. The 0 that was popped is pushed again, and then popped and not used.
The MEMEM function stores the return address in a byte variable. It should be a dword.
After calling LoadFile, the number of clusters is stored as a ImageSize, which is also a byte variable and should be a dword.
In KERNEL.EXE
I forgot to mention that you should turn off Incremental Linking under Configuration Properties => Linker.
The functions strcmp, strlen, strcpy and memset have to be linked in statically, so go to Configuration Properties => C++ => Code Generation and set Runtime Library to just Multi-threaded (not DLL or Debug), or implement these four functions by yourself.
- RGOS
- Member
- Posts: 38
- Joined: Sat Feb 13, 2010 10:52 am
- Location: Buurmalsen, The Netherlands
- Contact:
Re: MOV AX, 0x0000 doesn't work.
Hello,
Thanks for so much information, I checked all, but only where do you see Puts16 inlined twice? And the instructions in pressing the up-key are neccesary (I think you're talking about mov ah, byte[N], mov al, byte[M], mov ah, al, mov byte[N], ah, mov byte[M], al) because the variables directley in the mov instruction is not valid acording to NASM, and only one of them first in ah/al the if you're at the top choice and press the up-key nothing happens. I don't spot it. And in KERNEL.EXE do I still have to set Ignore All Default Libraries to no if I set Runtime Library to Multi-threaded? Because even if Multi-threaded is set, it doesn't build if Ignore All Default Libraries is set, I get errors about thethe unresolved external symbols, but I got 8 errors, one about __aullshr, three about _memset, one about _strcmp, one about __ chkstk, one about _strlen and one about _strcpy. And if I want to implement those functions myself, what do I have to implement? Do I have to, for example with _strcmp, compare two strings with one-another, or...? And then what about __aullshr, I haven't used it in my code (or else I can't find it) and I don't know what it's supposed to do, do you know that or is it findable on the internet?
[offtopic](Is findable even a word?).[/offtopic]
The new floppyimage is posted. Now the OS reports that the KERNEL.EXE is a bad image (it doesn't find the image signature). I'm going to play a little with it, and I post when i have a huge breaktrough...
Thanks.
Thanks for so much information, I checked all, but only where do you see Puts16 inlined twice? And the instructions in pressing the up-key are neccesary (I think you're talking about mov ah, byte[N], mov al, byte[M], mov ah, al, mov byte[N], ah, mov byte[M], al) because the variables directley in the mov instruction is not valid acording to NASM, and only one of them first in ah/al the if you're at the top choice and press the up-key nothing happens. I don't spot it. And in KERNEL.EXE do I still have to set Ignore All Default Libraries to no if I set Runtime Library to Multi-threaded? Because even if Multi-threaded is set, it doesn't build if Ignore All Default Libraries is set, I get errors about thethe unresolved external symbols, but I got 8 errors, one about __aullshr, three about _memset, one about _strcmp, one about __ chkstk, one about _strlen and one about _strcpy. And if I want to implement those functions myself, what do I have to implement? Do I have to, for example with _strcmp, compare two strings with one-another, or...? And then what about __aullshr, I haven't used it in my code (or else I can't find it) and I don't know what it's supposed to do, do you know that or is it findable on the internet?
[offtopic](Is findable even a word?).[/offtopic]
The new floppyimage is posted. Now the OS reports that the KERNEL.EXE is a bad image (it doesn't find the image signature). I'm going to play a little with it, and I post when i have a huge breaktrough...
Thanks.
- Attachments
-
- floppyimg.rar
- The newest floppy image.
- (11.39 KiB) Downloaded 86 times
Program development: Think, think more and think again, then find the solution and code it.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
Re: MOV AX, 0x0000 doesn't work.
Hello,
Of course. Why would you want default libraries linked in?And in KERNEL.EXE do I still have to set Ignore All Default Libraries to no if I set Runtime Library to Multi-threaded?
Implement those yourself. You know what those routines do (Basic C) so just impliment them. Or, as these are intrinsic's, you can disable them also so the compiler does not automatically use the built-in functions.And if I want to implement those functions myself, what do I have to implement? Do I have to, for example with _strcmp, compare two strings with one-another, or...?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
- RGOS
- Member
- Posts: 38
- Joined: Sat Feb 13, 2010 10:52 am
- Location: Buurmalsen, The Netherlands
- Contact:
Re: MOV AX, 0x0000 doesn't work.
Hello,
I've played a little and I now use the code in the attachment, but still I get the error (now the OS finds the signature), I'm going to expiriment with it and report if something is found.
EDIT: I'm now going to try and implement the functions myself.
Thanks.
I've played a little and I now use the code in the attachment, but still I get the error (now the OS finds the signature), I'm going to expiriment with it and report if something is found.
EDIT: I'm now going to try and implement the functions myself.
Thanks.
- Attachments
-
- KERNEL.ASM
- The new KERNEL.ASM (KERNEL.SYS).
- (2.64 KiB) Downloaded 71 times
Program development: Think, think more and think again, then find the solution and code it.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
Re: MOV AX, 0x0000 doesn't work.
There's a copy of the code in Puts16 where you print "Use the UP and DOWN keys to highlight your choice, and press ENTER to confirm" and where you print "Welcome to RGOS, please select operating system boot mode". That's where you could just call Puts16.
The unnecessary instructions could be replaced with:
There's no need to load [N] or store [M].
You can probably uncheck Ignore all default libraries if you use Multi-threaded as the Runtime Library.
__chkstk is used when a stack frame is larger than 4K. It can be removed by going into C/C++ => Command Line and adding the option /Gs10000000. However, in one of your functions you have a stack array which is 1.5MB in size. That won't work since stack is located at 0x90000 and downwards, and doesn't have enough room for the array. Are you sure you need such a large array? The rest of the functions can be taken from the runtime library, since they don't use anything else.
The PE signature is checked before the section loading code, so you don't need to check it afterwards. The header isn't copied to 0x100000, so it has to be accessed at 0x3000. The entire code after the TestImage label can be replaced with:
You don't need to load the segment registers in the beginning of KERNEL.EXE, since they're already loaded. There's a section named _CRT which references the imported symbol IsProcessorFeaturePresent. Perhaps the only way to get rid of this is to have ignore all default libraries on and implement the functions yourself. The __aullshr function is a function which shifts a 64-bit integer a specified number of bits to the right. This should be implemented in assembly.
The unnecessary instructions could be replaced with:
Code: Select all
mov al,[M]
mov [N],al
You can probably uncheck Ignore all default libraries if you use Multi-threaded as the Runtime Library.
__chkstk is used when a stack frame is larger than 4K. It can be removed by going into C/C++ => Command Line and adding the option /Gs10000000. However, in one of your functions you have a stack array which is 1.5MB in size. That won't work since stack is located at 0x90000 and downwards, and doesn't have enough room for the array. Are you sure you need such a large array? The rest of the functions can be taken from the runtime library, since they don't use anything else.
The PE signature is checked before the section loading code, so you don't need to check it afterwards. The header isn't copied to 0x100000, so it has to be accessed at 0x3000. The entire code after the TestImage label can be replaced with:
Code: Select all
mov esi,IMAGE_RMODE_BASE
mov ebx,[esi+60]
mov eax,[esi+ebx+40]
add eax,[esi+ebx+52]
call eax
cli
hlt
Re: MOV AX, 0x0000 doesn't work.
Now you've inserted code to copy the file into 0x100000 before the section loading code. That won't work since the section loading code expects ESI to point to IMAGE_RMODE_BASE. Just leave out the code that copies the entire file there and use the commented-out code to jump to the entry point (this gets the entry point from the header at IMAGE_RMODE_BASE).
- RGOS
- Member
- Posts: 38
- Joined: Sat Feb 13, 2010 10:52 am
- Location: Buurmalsen, The Netherlands
- Contact:
Re: MOV AX, 0x0000 doesn't work.
Hello,
I now have this code, is this what you ment?:
I, however, still get a stack fault, maybe it has to do something with that 1.5 MB stack, but where have you seen that, the only place where I did put somewhat on the stack is in MEMEM, but that was not to much (I don't ever beleive 1.5 MB) and besides thats commented out now.
Thanks.
I now have this code, is this what you ment?:
Code: Select all
jmp CODE_DESC:Stagekrn32
bits 32
Stagekrn32:
mov ax, DATA_DESC
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 90000h
call ClrScr32
call EnablePaging
; CopyImage:
; mov ecx, [ImageSize]
; movzx ebx, word [bpbBytesPerSector]
; imul ecx,ebx
; shr ecx,2
; cld
; mov esi, IMAGE_RMODE_BASE
; mov edi, IMAGE_PMODE_BASE
; rep movsd
; sectionloop:
; mov ebp,[esi+ebx]
; mov edi,[esi+ebx+4]
; add edi,IMAGE_PMODE_BASE
; mov ecx,[esi+ebx+8]
; cmp ecx,ebp
; jb vsize_ok
; mov ecx,ebp
; vsize_ok:
; sub ebp,ecx
; push esi
; add esi,[esi+ebx+12]
; rep movsb
; pop esi
; mov ecx,ebp
; mov al,0
; rep stosb
; add ebx,40
; dec edx
; jnz sectionloop
TestImage:
mov esi,IMAGE_RMODE_BASE
mov ebx,[esi+60]
mov eax,[esi+ebx+40]
add eax,[esi+ebx+52]
call eax
cli
hlt
Thanks.
Last edited by RGOS on Wed Feb 24, 2010 4:37 am, edited 1 time in total.
Program development: Think, think more and think again, then find the solution and code it.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
- RGOS
- Member
- Posts: 38
- Joined: Sat Feb 13, 2010 10:52 am
- Location: Buurmalsen, The Netherlands
- Contact:
Re: MOV AX, 0x0000 doesn't work.
Hello,
I've implemented my own functions of strcpy, strlen and strcmp, but the functions aullshr and memset don't work, because from aullshr I don't know the specifications, and memset is already a function, so I don't know why I get an error about it, this is the memset function:
Do you know what the problem is with memset? Do any of you know what the specifications of aullshr are (the parameters, the return value's, the types of all that), or where I can find it?
Thanks.
I've implemented my own functions of strcpy, strlen and strcmp, but the functions aullshr and memset don't work, because from aullshr I don't know the specifications, and memset is already a function, so I don't know why I get an error about it, this is the memset function:
Code: Select all
void *memset(void *dest, char val, size_t count)
{
unsigned char *temp = (unsigned char *)dest;
for( ; count != 0; count--, temp[count] = val);
return dest;
}
Thanks.
Program development: Think, think more and think again, then find the solution and code it.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
Re: MOV AX, 0x0000 doesn't work.
I have never heard of aullshr, so can't help you there. Why do you think you need it? As for the memset, one of the problems is that you write zeroes to array[1]..array[count], instead of array[0]..array[count-1]. The other is that you think for some reason you need temp. Why not simply do aRGOS wrote:Do you know what the problem is with memset? Do any of you know what the specifications of aullshr are (the parameters, the return value's, the types of all that), or where I can find it?Code: Select all
void *memset(void *dest, char val, size_t count) { unsigned char *temp = (unsigned char *)dest; for( ; count != 0; count--, temp[count] = val); return dest; }
Code: Select all
for (i = 0; i < count; i++)
{
((unsigned char*)dest)[i] = 0;
}
JAL
- RGOS
- Member
- Posts: 38
- Joined: Sat Feb 13, 2010 10:52 am
- Location: Buurmalsen, The Netherlands
- Contact:
Re: MOV AX, 0x0000 doesn't work.
Hello,
Thanks JAL, I've changed it, but it didn't solve the error, it's the linker that reports that memset is an unresolved external symbol, and aullshr is indeed the '>>' command, but I don't know how to fix the memset or the aullshr unresolved external symbol errors. The other commands I could do it, because from them I could find on the internet wich prameters they need, and what they have to return (I'm not that good at C/C++), but from aullshr I can't find it. For memset I'm going to give it a look (what I can make of it ).
Thanks.
Thanks JAL, I've changed it, but it didn't solve the error, it's the linker that reports that memset is an unresolved external symbol, and aullshr is indeed the '>>' command, but I don't know how to fix the memset or the aullshr unresolved external symbol errors. The other commands I could do it, because from them I could find on the internet wich prameters they need, and what they have to return (I'm not that good at C/C++), but from aullshr I can't find it. For memset I'm going to give it a look (what I can make of it ).
Thanks.
Program development: Think, think more and think again, then find the solution and code it.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
OS development: Don't think, think less and don't think again, then the solution will come, else you're screwed.
Most of the time at OSDev you're screwed.
Re: MOV AX, 0x0000 doesn't work.
Didn't think it would, given that it's the linker that gives the error, but still it's better to have a working memset.RGOS wrote:but it didn't solve the error
Could you give the exact linker error output (sorry, too lazy to check the previous pages to see whether you already did).it's the linker that reports that memset is an unresolved external symbol
A simple Google reveals this. But why would you want to shift 64-bit variables in 32-bit code? Ans why does the linker complain about memset, if you don't use memset yourself? Are you sure you aren't linking some standard libraries?and aullshr is indeed the '>>' command
JAL
Re: MOV AX, 0x0000 doesn't work.
Don't comment out sectionloop, it's the loading code. Besides, you've deleted the necessary part before it, which is:
This has to come before sectionloop.
__aullshr can be implemented in assembly like this:
Code: Select all
mov esi,IMAGE_RMODE_BASE
mov ebx,[esi+60]
cmp word [esi+ebx],'PE'
je ContinueLoad
mov ebx, BadImage
call Puts32
cli
hlt
ContinueLoad:
movzx edx,word [esi+ebx+6]
add ebx,256
__aullshr can be implemented in assembly like this:
Code: Select all
public __aullshr
__aullshr:
cmp cl,64
jae aus_0
cmp cl,32
jae aus_1
shrd eax,edx,cl
shr edx,cl
ret
aus_1:
and cl,31
shr edx,cl
xchg edx,eax
xor edx,edx
ret
aus_2:
xor eax,eax
cdq
ret