开发者

Borland c++ inline asm problem with WORD PTR and string

开发者 https://www.devze.com 2023-01-12 03:33 出处:网络
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 (somewh

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        
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号