MOV AX, 0x0000 doesn't work.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: MOV AX, 0x0000 doesn't work.

Post by Gigasoft »

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.
User avatar
RGOS
Member
Member
Posts: 38
Joined: Sat Feb 13, 2010 10:52 am
Location: Buurmalsen, The Netherlands
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by RGOS »

Hello,
Combuster wrote:
sar byte ptr ds:[eax+0x89501000], 0xc7
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 somewhere
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)).

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.
User avatar
RGOS
Member
Member
Posts: 38
Joined: Sat Feb 13, 2010 10:52 am
Location: Buurmalsen, The Netherlands
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by RGOS »

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.
Attachments
floppyimg.rar
The newest floppy image.
(11.61 KiB) Downloaded 125 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.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: MOV AX, 0x0000 doesn't work.

Post by Gigasoft »

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:

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
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:

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
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.
User avatar
RGOS
Member
Member
Posts: 38
Joined: Sat Feb 13, 2010 10:52 am
Location: Buurmalsen, The Netherlands
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by RGOS »

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... [-o< [-o< [-o<

Thanks.
Attachments
floppyimg.rar
The newest floppy image.
(11.39 KiB) Downloaded 87 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.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by neon »

Hello,
And in KERNEL.EXE do I still have to set Ignore All Default Libraries to no if I set Runtime Library to Multi-threaded?
Of course. Why would you want default libraries linked in?
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...?
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.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
RGOS
Member
Member
Posts: 38
Joined: Sat Feb 13, 2010 10:52 am
Location: Buurmalsen, The Netherlands
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by RGOS »

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.
Attachments
KERNEL.ASM
The new KERNEL.ASM (KERNEL.SYS).
(2.64 KiB) Downloaded 72 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.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: MOV AX, 0x0000 doesn't work.

Post by Gigasoft »

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:

Code: Select all

mov al,[M]
mov [N],al
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:

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
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.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: MOV AX, 0x0000 doesn't work.

Post by Gigasoft »

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).
User avatar
RGOS
Member
Member
Posts: 38
Joined: Sat Feb 13, 2010 10:52 am
Location: Buurmalsen, The Netherlands
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by RGOS »

Hello,

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
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.
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.
User avatar
RGOS
Member
Member
Posts: 38
Joined: Sat Feb 13, 2010 10:52 am
Location: Buurmalsen, The Netherlands
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by RGOS »

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:

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;
}
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.
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.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: MOV AX, 0x0000 doesn't work.

Post by jal »

RGOS wrote:

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;
}
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?
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 a

Code: Select all

for (i = 0; i < count; i++)
{
     ((unsigned char*)dest)[i] = 0;
}
?


JAL
User avatar
RGOS
Member
Member
Posts: 38
Joined: Sat Feb 13, 2010 10:52 am
Location: Buurmalsen, The Netherlands
Contact:

Re: MOV AX, 0x0000 doesn't work.

Post by RGOS »

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 :P).

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.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: MOV AX, 0x0000 doesn't work.

Post by jal »

RGOS wrote:but it didn't solve the error
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.
it's the linker that reports that memset is an unresolved external symbol
Could you give the exact linker error output (sorry, too lazy to check the previous pages to see whether you already did).
and aullshr is indeed the '>>' command
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?


JAL
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: MOV AX, 0x0000 doesn't work.

Post by Gigasoft »

Don't comment out sectionloop, it's the loading code. Besides, you've deleted the necessary part before it, which is:

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
This has to come before sectionloop.

__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
Locked