Page 1 of 1
Please check me this code
Posted: Fri Jul 15, 2005 8:39 pm
by Beastie
Hi guys
i really hated C and any high-level language so i rewrite all of my os lib libosdk in assembly.
can any body move his eyes on this code and tell if something wrong, specially the reboot one
?
thanks alot
all of this labels were made to called from C code.
Code: Select all
osdk_i386_lock:
CLI
RET
osdk_i386_unlock:
STI
RET
osdk_i386_in:
PUSH EBP
MOV EBP, ESP
PUSH DX
PUSH AX
MOV DX, WORD [EBP+8]
MOV AL, BYTE [EBP+12]
OUT DX, AL
POP AX
POP DX
POP EBP
RET
osdk_i386_out:
PUSH EBP
MOV EBP, ESP
PUSH DX
MOV DX, WORD [EBP+8]
IN AL, DX
POP DX
POP EBP
RET
osdk_i386_reboot:
CLI
REBOOT_LOOP:
IN AL, 64h
MOV AH, AL
AND AH, 01h
OR AH, AH
JZ REBOOT_END
PUSH AX
IN AL, 60h
POP AX
AND AL, 02h
OR AL, AL
JNZ REBOOT_LOOP
REBOOT_END:
MOV AL, 0FEh
OUT 64h, AL
HLT
HALT:
JMP HALT
Re:Please check me this code
Posted: Fri Jul 15, 2005 8:43 pm
by Beastie
BTW the reboot function was taken from a C one
Code: Select all
void osdk_i386_reboot(void)
{
unsigned temp;
osdk_i386_lock(); /* cli */
do{
temp=osdk_i386_in(0x64);
if((temp & 0x01)!=0)
{
(void)osdk_i386_in(0x60);
continue;
}
}while((temp & 0x02)!=0);
osdk_i386_out(0x64, 0xFE);
for(;;); /* in case of failure */
}
Re:Please check me this code
Posted: Sat Jul 16, 2005 3:37 am
by pini
I think the labels osdk_i386_in and osdk_i386_out have been swapped
For your reboot function, there's no need to do
after
, because flags are already set by and, especially ZF (the one you want)
I'm not sure, but doesn't the continue statement do another loop ?
Maybe you should move the REBOOT_END label after the pop ax, so that that test on temp & 0x2 is still done, according to your C code
Again, my understanding of the C continue statement may be false.
Re:Please check me this code
Posted: Sat Jul 16, 2005 9:25 am
by Beastie
i've testet my code and it worked on qemu...
here is my new snapshot
Code: Select all
BITS 32
GLOBAL osdk_i386_lock
GLOBAL osdk_i386_unlock
GLOBAL osdk_i386_in
GLOBAL osdk_i386_out
GLOBAL osdk_i386_reboot
GLOBAL osdk_i386_set_gdt_desc
GLOBAL osdk_i386_set_idt_desc
GDT:
GDT_LIMIT DW 0FFFFh
GDT_ADDR DD GDT_DESC
GDT_DESC:
TIMES 10000h DB 0h
IDT:
IDT_LIMIT DW 800h
IDT_ADDR DD GDT_DESC
IDT_DESC:
TIMES 800h DB 0h
osdk_i386_lock:
CLI
RET
osdk_i386_unlock:
STI
RET
osdk_i386_out:
PUSH EBP
MOV EBP, ESP
PUSH DX
PUSH AX
MOV DX, WORD [EBP+8]
MOV AL, BYTE [EBP+12]
OUT DX, AL
POP AX
POP DX
POP EBP
RET
osdk_i386_in
PUSH EBP
MOV EBP ,ESP
PUSH DX
MOV DX, WORD [EBP+8]
IN AL, DX
POP DX
POP EBP
RET
osdk_i386_reboot:
CLI
REBOOT_LOOP:
IN AL, 64h
MOV AH, AL
AND AH, 01h
OR AH, AH
JZ REBOOT_END
PUSH AX
IN AL, 60h
POP AX
AND AL, 02h
OR AL, AL
JNZ REBOOT_LOOP
REBOOT_END:
MOV AL, 0FEh
OUT 64h, AL
HLT
HALT:
JMP HALT
SET_GDT_SEG_DESC:
PUSH EDI
PUSH EDX
PUSH ECX
PUSH EBX
PUSH EAX
;; ASSUMES BX=NUMBER, ESI=POINTER TO DESC
MOV EDI, GDT_DESC
MOV EAX, 08h
MUL BX
ADD EDI, EAX
CLD
MOV CX, 08h
REP MOVSB
POP EAX
POP EBX
POP ECX
POP EDX
POP EDI
RET
osdk_i386_set_gdt_desc:
PUSH EBP
MOV EBP, ESP
PUSH ESI
PUSH EBX
MOV EBX, [EBP+8]
MOV ESI, [EBP+12]
CALL SET_GDT_SEG_DESC
POP EBX
POP ESI
POP EBP
RET
SET_IDT_SYS_DESC:
PUSH EDI
PUSH EDX
PUSH ECX
PUSH EBX
PUSH EAX
;; ASSUMES BX=NUMBER, ESI=POINTER TO DESC
MOV EDI, IDT_DESC
MOV EAX, 08h
MUL BX
ADD EDI, EAX
CLD
MOV CX, 08h
REP MOVSB
POP EAX
POP EBX
POP ECX
POP EDX
POP EDI
RET
osdk_i386_set_idt_desc:
PUSH EBP
MOV EBP, ESP
PUSH ESI
PUSH EBX
MOV EBX, [EBP+8]
MOV ESI, [EBP+12]
CALL SET_IDT_SYS_DESC
POP EBX
POP ESI
POP EBP
RET
LOAD_GDT:
GDTA DD GDT
LGDT [GDTA]
RET
LOAD_IDT:
IDTA DD IDT
LIDT [IDTA]
RET
Re:Please check me this code
Posted: Sat Jul 16, 2005 10:51 am
by pini
Sorry, but I'm currently too busy, so I'm not able to look deeply to the code you posted. I will, but later.
What I was saying is that the osdk_i386_in and osdk_i386_out are wrapper to use the 'in' and 'out' mnemonics in C, right ? But in the code you posted, osdk_i386_in is a wrapper to the 'out' mnemonic, while osdk_i386_out is a wrapper to the 'in' mnemonic.
For the reboot function, I would expect it to work 'as if' in both qemu and bochs and others, because these are emulators, and thus don't suffer from time latency while reading/writing to ports. I don't know if it'll work with real hardware, but it may. I didn't checked to correctness of the reboot algorithm, I just noticed that C and Asm versions were not based on the same algorithm.
Cheers.
Re:Please check me this code
Posted: Sat Jul 16, 2005 11:05 am
by Beastie
for the in and out , i've swapped them, i'm a big idiot, i will correct it. thanks
btw i wrote this code at 4:30 AM so you will find alot of stupidity here
about the reboot i will try to test it on real hw. or i will use a different algorithm like those which depends on lidt and faults.
for the gdt and idt any notice ?
Re:Please check me this code
Posted: Sat Jul 16, 2005 11:12 am
by mystran
I'd say, whether you like high-level language or not, you should definitely learn to comment. It's even more important for assembler, because assembler is so regular looking, making it hard to follow long listings of code without reading each and every line.
Now, while I don't think C is my dream-language, I definitely fail to understand why people bother with assembler, if they still write C-style, block-structured code. I'd move to higher abstraction levels, not lower.
But the main point is, help yourself, and comment your code while you write it.. it'll make your life a lot easier. I promise. (Why actually had a rather good thread about commenting lately, which you might find useful.)
Re:Please check me this code
Posted: Sat Jul 16, 2005 11:17 am
by Beastie
i always use comments but here there is a limit to the post and this code is not too long or too complex.
Re:Please check me this code
Posted: Sat Jul 16, 2005 12:57 pm
by mystran
There is an attachment feature as well, so you can put the code in a file and ask people to read it from there.