I am writing small kernel for the 8086 processor (Working in BC3.1, on Windows XP as host operating system). Kernel is multithreaded, so I have problems when I use printf or cout for debugging (somewhere in code, printf sets InterruptEnable flag to 1, and my timer interrupt routine calls dispatch and my code breaks down).
Because of that,开发者_StackOverflow社区 I wrote simple puts function in inline asm:
void _printf(char *c)
{
//setup data
asm{
mov ch, 10
mov cl, 0
mov ah, 0x2
mov bx, WORD PTR c
}
loop: asm{
//\0?
cmp [bx], cl
je exit_prc
mov dl, [bx]
int 0x21
inc bx
//is there \n?
cmp [bx], ch
je newline
jmp loop
}
exit_prc: return;
newline: asm{
//insert cr char
mov dl, 0xD
int 21h
jmp loop
}
}
Now, I call it somewhere in, lets say PCB::PCB() like this:
_printf("Counstructor PCBa\n"); and it works fine. However, when I call it somewhere else, in some other file with other string it outputs for example "tructor PCBa\n".I don't have a clue what is going on. Memory model is huge.
First of all, at least in my opinion, you've chosen a rather poor name -- what you have is pretty much a puts
, not a printf
. Second, for what you're trying to accomplish, you might want to try using Borland's cprintf
, cputs
, and such -- they use the DOS console output routines, and there's a pretty decent chance they don't enable interrupts.
If that won't work, there still seems to be little reason to use inline assembly. I'd do something like this:
// warning: untested -- and it's been a while since I wrote any code like this,
// so it's probably a little wrong.
//
void myputc(char ch) {
union REGS in, out;
// set up registers here:
in.h.ah = 2;
in.h.dl = ch;
intdos(&in, &out);
}
void myputs(char huge *s) {
while (*s) {
if (*s == '\n')
myputc('\r');
myputc(*s++);
}
}
If you really want to use assembly language, my advice would be to write it as a separate module of pure assembly language:
; Again: not tested and I haven't done this in a while, so use with care.
;
.model large, c
.code
LF = 10
CR = 13
putc proc
mov dl, al
mov ah, 2
int 21h
ret
putc endp
puts proc string: ptr char
mov si, string
lodsb
next:
cmp al, LF
jnz printit
mov dl, CR
mov ah, 2
int 21h
printit:
mov dl, al
mov ah, 2
int 21h
lodsb
test al, al
jnz next
ret
puts endp
end
精彩评论