Page 1 of 1

CALL opcode and INT 0

Posted: Fri May 02, 2008 1:00 pm
by inflater
Hi,
I have following code in my OS:

Code: Select all

procedure PMain; stdcall; [public, alias: 'PMain'];
label test;
begin
asm 
test: 
cmp cx,3 
jne test
end;
...
...
It's the main(); function, and functions in it weren't working (writestr("hello world") for example, so I fired up Bochs debugger:

After the JNE TEST comes this (I suppose it's the handler code for the "end;" directive):

Code: Select all

mov eax, 0x00000005
call word ptr ds:0x110
--DIVIDE BY ZERO ERROR--
cli
jmp .+0xfffffffe
Why does the call opcode trigger divide by zero error? I think the call opcode is trying to jump somewhere off, or is something misaligned?

Thanks in advance.

Re: CALL opcode and INT 0

Posted: Fri May 02, 2008 2:55 pm
by Dex
Does it still do the same with this ?

Code: Select all

procedure PMain; stdcall; [public, alias: 'PMain'];
begin
asm 
@@1: 
cmp cx,3 
jne @@1
end;
...
...

Posted: Sat May 03, 2008 1:25 am
by inflater
Unfortunately yes, every code of block that reaches the END; statement seems to create the divide error, so I tried to create a infinite loop ASM block to see what is happening...

I try to align the IDT, GDT seems to be aligned and such...
Also this may be the error: who uses sections? I don't have them declared in STUB.ASM, should I? BSS for stack, TEXT for code and DATA for ... data?
Well, I give it a try.

Regards
inflater

Posted: Sat May 03, 2008 4:31 am
by inflater
Well, the END; part calls after the mov eax,0005 this: "call dword ptr [esi]". So that means, ESI is incorrect, because it jumps right into the strings part of my OS, where it causes havoc and triggers weird exceptions.

Posted: Sat May 03, 2008 7:16 am
by Laksen
Is your stack setup correctly? esp and ebp

Posted: Sat May 03, 2008 9:02 am
by inflater
Hmm... Seems the compilation process is okay, I tried TASM + VALX + NASM all compiled to OBJ and linked to EXE, and I've tried also FPC set to gnu assembler (aout), NASM set to aout and LD set to target EXE. It makes almost the same error, but this time it jumps into zeros (preferably stack space) and at the end Bochs shows

Code: Select all

fetch_raw_descriptor: LDTR.valid=0
but I couldn't get the instrunction where was the exception because Bochs crashed. It's starting to get very weird...

Stack and ebp are initialized properly I think:

Code: Select all

push 0x0FFFFFFFF
	push 0x0AAAAAAAA
	pop  ebx
	pop  eax
works and in the debugger confirmed the EAX and EBX's contents.

//EDIT: Now it writes
00051815685i[CPU0 ] math_abort: MSDOS compatibility FPU exception
00051815691e[CPU0 ] iret: return CS selector null
00051815691e[CPU0 ] interrupt(): gate.type(1) != {5,6,7,14,15}

OMFG this is sick!

Posted: Sat May 03, 2008 9:49 am
by inflater
Can anyone help me please?

Posted: Sat May 03, 2008 10:25 am
by inflater
Okay, now I've tried to omit the TASM part and NASM does work... weird.

My COMPILE.BAT now looks like this:

Code: Select all

del *.obj *.o *.s *.ppu *.bin
nasm -f obj stub.asm -o stub.obj
rem pause
fpc -Anasmobj -n -Sc -Sm -Sg -Xd -Rintel -XX kernel.pas
rem pause
link stub.obj kernel.obj system.obj console.obj,KERNEL.EXE
apack -x -t KERNEL.EXE KERNEL.BIN
ren kernel.bin PXLDR.BIN
if exist kernel.bin del kernel.bin
if exist kernel.exe del kernel.exe
del *.obj *.o *.map *.s *.ppu
pause
It will: compile the stub.asm, compile the asm and pascal sources, OPTLINK will link all the OBJ files into one exe file. And what do we got here? Well, let's see how Bochs will respond at this code:

Code: Select all

label test;
procedure PMain; stdcall; [public, alias: 'PMain'];
begin
        asm
test:
	cmp cx,3
	jne test
	end;
end;
Bochs debugger:

Code: Select all

call .+0x00000002
(Entering function PMain)
push bp
mov bp, sp
(Yay! We're past the ASM directive! But why FreePascal doesn't use EBP and ESP?)
cmp ecx, 0x850f0003
(wtf? It should be 3!)
clc
dec ecx
ret
(What the **** has happened?! It shouldn't be there!)
bx_dbg_read_linear: physical memory read error
I don't think it's because my RAM is faulty, because it doesn't work everywhere...
This same applies for VALX.

What should I do now? I'm totally pissed off now :(

Posted: Sat May 03, 2008 11:33 am
by Combuster
I doubt there are much people with the needed experience in freepascal to answer that.

Could you post (for one and the same instance of the problem):
1: the pascal code of the crashing function
2: the full disassembly of that function
3: the bochs log
4: a debug session printing the register and stack contents at the start of the function
5: the same information just before the crash.

That way we may get a more sensible diagnosis of the problem.

-----

Oh well, you posted a bit of that in the meantime.

It looks like you are mixing 16 and 32 bit code and environments. Have a look at the assembly output generated by freepascal to see if it expects to be run in 16-bit or 32-bit environment, and use that to make the assembler stage emit the proper output, then check wether the system is running in that expected mode when it reaches that code.

right now, the disassembly reads cmp ecx, 0x----0003, where it should probably have been cmp cx, 3; opcode containing 0x850f

Posted: Sat May 03, 2008 11:57 am
by inflater
Well, I have somehow managed to get this working:

Code: Select all

unit kernel;

interface

implementation

label test;

procedure PMain; stdcall; [public, alias: 'PMain'];
begin
asm
test:
cmp cx,3
jne test
end;
end;

end.
Bochs debugger shows this:

Code: Select all

call .+0x00005014
(below: in function PMain, entering ASM directive)
push ebp
mov ebp, esp
(finished initialization of asm directive, below: the code itself)
cmp cx, 0x0003
jnz .+0xfffffffa
(code is alright)
leave
ret
(above:successful ending of directive END :))
jmp .+0xfffffffe (jmp $)
(end of function PMain, in STUB.ASM)
I used TASM to compile the assembly files generated by free pascal. (Using NASM it didnt work). So this worked, but TASM couldn't compile the unit PATSCREEN:

Code: Select all

**Error** screen.s(302) CS unreachable from current segment
- weird.
Combuster wrote:It looks like you are mixing 16 and 32 bit code and environments.
Actually no, the STUB.ASM will switch to protected mode before executing the function PMAIN.

I think I will download the original barebone freepascal OS, including the multiboot specifications, and if it would work, I will just load the OS with GRUB, after getting data from multiboot tables I'll just drop down the protected mode, go into real mode (for initializing OS specific functions etc) and go back into pmode. :)
//EDIT: It seems that I can't. The whole bloated thing of course must be in ELF, LD doesn't support 32bit OMF and it must have these multiboot stupid routines. Ah well, time to check to AnonymOS.

Posted: Sat May 03, 2008 1:25 pm
by Laksen
I just use the internal assembler. My "make" looks like this:

nasm -f elf -o stub.ob stub.asm
fpc -Aelf -Cn -n -O2 -Si -Sc -vi -Sm -Sg -Rintel kernel.pas
elf-ld -T os.lkr -o kernel.bin *.ob *.o
del *.ob *.o

using Nasm and binutils

Posted: Sat May 03, 2008 1:54 pm
by inflater
What's the program "elf-ld"? I didn't found it in my tool chain..

Posted: Sat May 03, 2008 2:23 pm
by Laksen
just ld with elf emulation for windows. I can upload it if you want it

Posted: Sun May 04, 2008 12:45 am
by Combuster
wouldn't that be equivalent to the ld built with the GCC Cross-Compiler tutorial?