【发布时间】:2010-08-15 16:33:40
【问题描述】:
我正在为 8086 处理器编写小内核(在 BC3.1 中工作,在 Windows XP 上作为主机操作系统)。内核是多线程的,所以当我使用 printf 或 cout 进行调试时会遇到问题(在代码中的某处,printf 将 InterruptEnable 标志设置为 1,并且我的计时器中断例程调用调度并且我的代码发生故障)。
因此,我在内联 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”。
我不知道发生了什么。内存模型很大。
【问题讨论】:
-
你是从定时器 ISR 调用这个? DOS 不可重入。
-
No.. 定时器 ISR 只做上下文切换。我可能有 20 多个线程,并且我也有信号量和事件实现。因此,当我的应用程序挂在某个实施不佳的 wait() 上时,我无法使用调试器对其进行跟踪,我唯一的选择是打印队列大小/元素和代码中的当前行以及线程 ID。但是,如果我使用标准 puts() 执行此操作,我的 Timer ISR 会在 puts 内部的某处被调用,它会导致在没有调试器的情况下运行时没有运行的上下文切换。
-
很抱歉,除了您的问题之外还问您。我正在使用 Borland Turbo C++ 3。如果我想编写内联汇编程序,我必须在列表中包含什么标题?我的意思是,我必须在#include
上添加什么以使编译器可以理解程序集?我试图只包含 iostream.h、stdio.h、stdlib.h,但没有工作。 -
@AirCraftLover 对不起,我不记得了,上次我这样做是在 10 年前,但是 AFAIK,你不需要包含任何特别的东西 - 这是编译器支持的一部分.也许打开一个新问题并在那里发布一个最小示例(有错误?)。
标签: c++ assembly inline-assembly