Page 1 of 1
Problems with INT services
Posted: Mon Nov 14, 2005 7:30 pm
by Cjmovie
I'm actually very close to putting this under "general programming", but oh well.
Problem:
Calling a function which calls a function which calls a function causes problems when passing an address (to a string), making it jibberish input to the final function.
I have code as such:
Code: Select all
UINT arg;
void ThisFunc(char* a){
arg = (UINT)a;
ThatFunc();
}
ASM:
_ThatFunc:
mov ebx, [_arg]
int 0x55
ret
_int55:
push ebx ;Push argument to c code in kernel
call _ThatCFunction
pop ebx
iret
More C-Code
void ThatCFunction(char* a){
PrintString(a);
}
My problem? it doesn't seem to be passing the correct address for the string. The INT 55 is part of the kernel, the other 2 are part of the program it is executing. For some reason, the kernel gets the address 0x00000001 instead of 0x00001000. Even weirder, if I replace the line:
with
It works! Any idea what could cause this? Kind of on the end of my head right now, really odd problem....
Thanks for any help
Re:Problems with INT services
Posted: Tue Nov 15, 2005 2:36 am
by Candy
Did you try single-stepping that bit of code with Bochs (debugging version) to see which instructions were executed in both cases?
If not, please do so. You will figure out the cause yourself and you'll understand why and how much better.
Re:Problems with INT services
Posted: Tue Nov 15, 2005 3:20 am
by Pype.Clicker
so roughly, that means all you've written is correct but your program that calls int55 isn't quite correctly linked ... right ?
Re:Problems with INT services
Posted: Tue Nov 15, 2005 3:31 pm
by Cjmovie
I did step through it, everything looks fine except instead of the correct address of the string data (0x00001000) it has a seemingly random address (0x00000001).
Heres something else weird I noted after trying out my code with two ints: For some reason, some calls to asm code are being cut out by the compiler or whatnot: For instance, I have one ASM code function that does "mov ax, 0x00\n int 0x50" and another that does "mov ax, 0x01\n int 0x50". I can call either one as much as I like, but if I do a call to the first function _at the start of the program_, it never generates the call to the function! I then tried using inline ASM for it -> same results, it cut it out.
I have a feeling this might be, in fact, either a compiler problem (on my side, probably) or something with linking it. If I do both files (the services.asm and main function) in ASM, it works fine.
Re:Problems with INT services
Posted: Tue Nov 15, 2005 3:32 pm
by Cjmovie
Oops, knowing this might help:
Compilation Script:
Code: Select all
gcc -c -ffreestanding -I./Kernel/Include -O Apps/Shell.c -o Apps/Shell.o
nasm Apps/Services.asm -o Apps/Services.a -f elf
ld -T Apps/Shell.ld -o Apps/Shell.o.ld Apps/Services.a Apps/*.o
objcopy -S -O binary Apps/Shell.o.ld Object/Shell.APP
Linker Script:
Code: Select all
ENTRY(_Main)
phys = 0x00000000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
}
end = .;
}
Re:Problems with INT services
Posted: Tue Nov 15, 2005 4:50 pm
by AR
Are you using segmentation or a higher half kernel? If not then that link address (0x00000000) will yield a broken binary that will access data pointers in the wrong part of the address space.
Re:Problems with INT services
Posted: Tue Nov 15, 2005 6:11 pm
by Cjmovie
Paging
.
Kernel at 0xc000000, shared librarys/message qeue at 0x80000000, program/data at 0x00000000.
Re:Problems with INT services
Posted: Thu Nov 17, 2005 4:18 pm
by Cjmovie
Where did all those last few posts go? Did it have something to do with the forum not working earlier?
Anyways, post again I must.
I'm getting a GPF if a task switch occurs during the execution of an INT. I have switched the int type from to a TRAP gate, as pype recommended. When I get the error:
EFLAGS: 0x10002 (Aren't the top 16 bits reserved/0?)
Error Code: 0x210
Code:
(Application)
Code: Select all
global _PrintString
global _ClearScreen
global _ArgA
global _Main
_Main:
;call _ClearScreen
.L1
mov ebx, StrN1
call _PrintString
jmp .L1
call _GetChar
mov ebx, StrN2
call _PrintString
ret
_ClearScreen:
mov ax, 0x00
int 0x50 ;Call text services
ret ;Return to C code
_PrintString:
mov ax, 0x01
int 0x50 ;Call text services
ret ;Return to C code
_GetChar:
.Le1:
mov ax, 0x02
int 0x50
;cmp al, 0
;je .Le1
ret
StrN1 db "Hello world! Type a letter:", 10, 0
StrN2 db 10, "You typed a letter!", 10, 0
(I have the infinite print string loop so that it almost garuantees it will be running an INT while a task switch occurs/IRQ0.
(INT handler)
Code: Select all
;Text mode services handler!
extern _ClearScreen
extern _PrintString
extern _GetChar
global _SRV_TextModeService
_SRV_TextModeService:
cmp ax, 0x00 ;Clear Screen?
je ClearScreenService ;Yes
cmp ax, 0x01 ;Print String?
je PrintStringService ;Yes
cmp ax, 0x02 ;Getchar?
je GetCharService ;Yes
iret ;Invalid function, just return
ClearScreenService: ;Clear screen function
call _ClearScreen ;Clear the screen (call C code)
jmp ServiceCommonReturn
PrintStringService: ;Print string function
push ebx ;Push argument to C code, pointer to string
call _PrintString ;Print it (call C code)
add esp, 4
jmp ServiceCommonReturn
GetCharService:
.L1:
xor eax, eax
call _GetChar
cmp al, 0
je .L1
jmp ServiceCommonReturn
ServiceCommonReturn:
cli
iret
(Task Switch Handler)
Code: Select all
global _ASM_TaskStub
extern _MT_SwitchTask
extern _CurrentCR3
;When called by an IRQ from processor, allows task switches
_ASM_TaskStub:
cli
pushad ;Push all general purpose registers
push ds ;Push data segment
push es ;Push data segment 'e'
push fs ;Push data segment 'f'
push gs ;Push data segment 'g'
mov eax, esp ;Get current stack pointer
push eax ;Push it as argument to C function
call _MT_SwitchTask ;Call 'C code' task scheduler
add esp, 4 ;Clean up pushed argument to 'C code'
mov esp, eax ;Set new task's stack pointer. (EAX from C code return value)
mov eax, [_CurrentCR3] ;Get CR3 from C code data
mov cr3, eax ;Set new CR3 for task
pop gs ;Pop off data segment 'g'
pop fs ;Pop off data segment 'f'
pop es ;Pop off data segment 'e'
pop ds ;Pop off data segmemt
popad ;Pop all general purpose registers
iret ;Interrupt Return. Installs EIP etc. of new task
Re:Problems with INT services
Posted: Thu Nov 17, 2005 4:20 pm
by Cjmovie
Also, somehow the code segment (Kernel one, 0x08) gets put into GS...The others, including the real code segment (in CS) is set correctly.
Re:Problems with INT services
Posted: Thu Nov 17, 2005 4:36 pm
by Cjmovie
Oi! Another one of those "I'm such an idiot" moments!
I redid all of my task switching code, and it worked perfect...until the stack was changed from where it left it! I had forgotten to save new ESP values on task switch....Anyways, still got good things done from the process, such as trap gates instead of interrupt gates, and some little things in my service code.
Re:Problems with INT services
Posted: Fri Nov 18, 2005 11:11 pm
by Cjmovie
I'm back to the first problem: GCC is cutting out some of my ASM, even though I clearly have declared it using "volatile". Here is what bochs says the code looks like:
Code: Select all
Next at t=9351387
(0) [0x01ff8000] 0018:00000000 (unk. ctxt): push ebp ; 55
<bochs:3> s
Next at t=9351388
(0) [0x01ff8001] 0018:00000001 (unk. ctxt): mov ebp, esp ; 89e5
<bochs:4> s
Next at t=9351389
(0) [0x01ff8003] 0018:00000003 (unk. ctxt): mov ax, 0x1 ; 66b80100
<bochs:5> s
Next at t=9351390
(0) [0x01ff8007] 0018:00000007 (unk. ctxt): int 0x50 ; cd50
<bochs:6> s
Next at t=9351391
(0) [0x00110ef0] 0008:c0000ef0 (unk. ctxt): pushad ; 60
<bochs:7> s
Next at t=9351392
(0) [0x00110ef1] 0008:c0000ef1 (unk. ctxt): push ds ; 1e
<bochs:8> s
Next at t=9351393
(0) [0x00110ef2] 0008:c0000ef2 (unk. ctxt): push es ; 06
<bochs:9> s
Next at t=9351394
(0) [0x00110ef3] 0008:c0000ef3 (unk. ctxt): push fs ; 0fa0
<bochs:10>
Here is the C source:
Code: Select all
void ClearScreen(){
__asm__ __volatile__ ("mov %0, %%ax" : : "I" (0x00));
__asm__ __volatile__ ("int $0x50");
}
void PrintString(char* c){
__asm__ __volatile__ ("mov %0, %%ax" : : "I" (0x01));
__asm__ __volatile__ ("mov %0, %%ebx" : : "i" (c));
__asm__ __volatile__ ("int $0x50");
}
int Main(int argc, char* argv[]){
PrintString("Hello World!");
return 0;
}
Not really sure what's going on here
. It completly cuts out the MOV for EBX, which is where the pointer to the string should go. This makes it print out bogus data (which happens to be wherever EBX points to, in this case it being 0x00000000).
Re:Problems with INT services
Posted: Fri Nov 18, 2005 11:25 pm
by AR
At a guess, I'd suggest using "g"(c) instead of "i"(c). You may also want to combine that code together:
Code: Select all
__asm__ ("mov %0, %%eax\n\t"
"mov %1, %%ebx\n\t"
"int $0x50" : : "I"(0x01), "g"(c));
Or even:
Code: Select all
__asm__ ("int $0x50" : : "a"(0x01), "b"(c));
Re:Problems with INT services
Posted: Fri Nov 18, 2005 11:48 pm
by Cjmovie
Well this is interesting. It seems my "entry" directive in my link script was, in an odd way, being ignored. It was entering into the _ClearScreen_ Function, causing it to clear the screen every time without doing anything else.
I thought about it, so I moved the functions below Main and added declarations for them. Sure enough, it worked. Any idea why that's happening?
Link Script:
ENTRY(_Main)
phys = 0x00000000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
}
end = .;
}
Compile Batch File:
@echo off
gcc -c -ffreestanding -O Apps/Main.c -o Apps/Main.a
ld -T Apps/Shell.ld -o Apps/Shell.o.ld Apps/Main.a
objcopy -S -O binary Apps/Shell.o.ld Object/Shell.APP
bin\GenFileSys floppy.img Object\boot.bin Object\Kernel.KRNL Object\Shell.APP
bin\dd if=object\stage2.bin of=floppy.img obs=512 count=72 seek=2808
Thanks for your help though, my code looks a lot more pretty now
. That, and it made me learn a new inline ASM format
.
Re:Problems with INT services
Posted: Fri Nov 18, 2005 11:52 pm
by AR
I'd say that has something to do with the objdump converting, you may want to link directly to a flat binary output.