[OS DEV] Przekazywanie parametrów z C do ASM

0

Witam,

Piszę swojego pierwszego OS'a i problem napotkałem w dość nieoczekiwanym miejscu, na samym początku mojej przygody. Chciałem napisać funkcję w asm (NASM) i wywołać ją z parametrem w głównym kodzie napisanym w C (DJGPP) . Funkcja miała wyświetlać pojedynczy znak ( funkcja 0eh przerwania 10h ) no ale niestety tak się nie dzieje. Zamiast tego wyświetla ,jakby to inaczej nazwać....spację( puste pole). Wywołanie przerwania jest na poprawne bo gdy podam numer zanku w kodzie ASM to wszystko wyświetla jak powinno. Sądzę że wina leży gdzieś po stronie źle ustawionego stosu ,jednak nie mogę wykryć błędu, a próbowałem już na wszystkie sposoby.

Oto "kod" mojego os'a:

Funkcja wyświetlająca znak:

[BITS 32]

section .text use32 


global _writestr

_writestr:

push ebp
mov ebp,esp
mov al,[ebp+8]
mov ah,0eh
mov bh,0x00
mov bl,0x07
int 0x10
mov ebp,esp
pop ebp

ret

Kod w C wywołujący funkcję wyświetlającą znak:

extern void _writestr(char c);
void start(void)
{
writestr('T');
while(1);
}

Kod startowy kernela:

[BITS 32]

[EXTERN  _start]

mov eax,cs
mov ds,eax
mov es,eax


cli
mov eax,0x5000
mov ss,eax
mov eax,0x5200
mov esp,eax
sti
xor eax,eax
 
call _start

Kompilacja:


 nasm -f coff kernel.asm  -o kernelent.o
 nasm -f coff k_asmcode.asm -o k_helper.o
 gcc -c kernel.c  -o kernel.o
 ld -Map kernel.map kernelent.o  kernel.o k_helper.o -Tkernel.ld -o kernel.bin
 copy kernel.bin a:\kernel.bin

BOOT loader jest raczej ok , bo nie był pisane przeze mnie :-) System testuję na bochsu

System ma jak na razie pracować w real mode.

I teraz pytanie "trolowatego dziecka neostrady" ;-) : Co tu do ch..... jest nie tak?

Pozdrawiam i z góry dziękuję za Wasz trud,
W2K</asm>

0

Coprawda nie wiem dlaczego masz puste pole ale myślę, że raczej problemem jest wywołanie funkcji z przerwania. W każdym razie znalazłem pare błędów w Twoim kodzie.

push ebp
mov ebp, esp <---- to i komenda wyżej są w ogóle nie potrzebne jeśli nie modyfikujesz stosu. Tak więc wywal je
mov ebp,esp  <---- powinno być mov esp, ebp ale jeśli wywalisz kawałek z góry to ten także
pop ebp
ret <--- daj ret 4. Wrzuciłeś jeden 4 bajtowy parametr na stos dlatego powinieneś na końcu funkcji go wyrównać.
0

Myślę że przerwanie jest wywoływane dobrze,tym bradziej że podobny efekt jest , gdy próbuję bezpośrednio odwołać się do pamięci karty pod adres 0xb800. Kod jest skopiowany z kursu assemblera więc jest raczej poprawny. Sprawdzałem dzisiaj na swoim komputerze ( nie poprzez emulator) i dzieje się to samo.

0
W2K napisał(a)

Kod jest skopiowany z kursu assemblera więc jest raczej poprawny.

no wiesz, jak funkcja kończy się przez mov ebp, esp to kod raczej nie jest poprawny.
W definicji funkcji writesrt spróbuj dodać słowo kluczowe __stdcall

0

Hmmm, wydaje mi sie czy rmode jest 16-bitowy :> ???
To czemu uzywasz [bits 32] i rejestrow eax, ebx, etc????????????
Jesli zle gadam to mnie poprawcie :P

//Edit: LD i gcc tez na 99% są 32 bitowe i nie skompilujesz kodu pod rmode ;-P

1 użytkowników online, w tym zalogowanych: 0, gości: 1