我正在为8086处理器编写小内核(在BC3.1中工作,在Windows XP上作为主机操作系统)。内核是多线程的,所以当我使用printf或cout进行调试时遇到问题(代码中的某处,printf将InterruptEnable标志设置为1,而我的定时器中断例程调用dispatch并且我的代码出现故障)。
因此,我在内联asm中编写了简单的puts函数:
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
}
}
现在,我把它称之为某处,比如说PCB :: PCB()就像这样:
_printf(“Counstructor PCBa \ n”);
它工作正常。但是,当我在其他地方调用它时,在其他字符串中使用其他字符串输出例如“tructor PCBa \ n”。
我不知道发生了什么。记忆模型很大。
答案 0 :(得分:2)
首先,至少在我看来,你选择了一个相当差的名字 - 你所拥有的几乎是puts
,而不是printf
。其次,对于你想要完成的任务,你可能想尝试使用Borland的cprintf
,cputs
等等 - 他们使用DOS控制台输出例程,并且他们有相当不错的机会启用中断。
如果这不起作用,似乎没有理由使用内联汇编。我会做这样的事情:
// 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++);
}
}
如果您真的想使用汇编语言,我的建议是将其编写为纯汇编语言的单独模块:
; 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