From OSDev Wiki
Jump to: navigation, search

Hello I'm Superleaf1995, a C and Assembly coder that has build a lot of MS-DOS programs.


Send a happy face to COM1:

typedef int i;typedef void v;typedef char c;i z(){return inb(0x3F8+5)&32;}w(c a){while(!z()){}outb(0x3F8,a);}u(){w(':');w(')');}

390 Bits

stack preparation for thread switching:

/* follows MVS calling convention (used by gccmvs) */
void SchedPrepareThreadStack(struct thread* thread)
    /* R13 is used as a stack pointer, now we have to setup a few things up */
    thread->context.r15 = (unsigned int)thread->stack + stack_size;
    /* stack+76 should point to stack+180 (because this would be the next frame!) */
    *((uint32_t *)(&((uint8_t *)thread->stack)[76])) = (&((uint8_t *)thread->stack)[180]);
    *((uint32_t *)(&((uint8_t *)thread->stack)[8])) = (&((uint8_t *)thread->stack)[180]);
    /* Set backchain to 0 for stack unwinding */
    *((uint32_t *)(&((uint8_t *)thread->stack)[4])) = NULL;
    *((uint32_t *)(&((uint8_t *)thread->stack)[8])) = NULL;

stack unwinding:

int DbgUnwindStack(cpu_context *ctx_frame)
    extern uint32_t __stack[1024]; /* your kernel stack*/
    uint8_t *frame = (uint8_t *)ctx_frame->r13;
    /* Corrupt stack pointer? */
    if((ptrdiff_t)frame < (ptrdiff_t)&__stack) {
        KeDebugPrint("Potentially corrupt stack, (SP=%x)\r\n", (unsigned int)frame);
        frame = (uint8_t *)&__stack;
    /* Pointer to top of the stack */
    while(frame != NULL) {
        /* R14 is stored on frame+12; and holds the address of the return point of the caller */
        uint32_t retaddr = *((uint32_t *)&frame[12]);
        struct DebugSymData *retsym = DbgGetSymbol((void *)retaddr);
        /* And R15 is also stored on frame+16, and contains the branching/base address of the callee */
        uint32_t calladdr = *((uint32_t *)&frame[16]);
        struct DebugSymData *callsym = DbgGetSymbol((void *)calladdr);
        if(retsym != NULL) {
            KeDebugPrint("RET=(%i=%s:%i)\r\n", (unsigned int)retaddr, retsym->name, (int)((ptrdiff_t)retaddr - (ptrdiff_t)retsym->addr));
        if(callsym != NULL) {
            KeDebugPrint("CALL=(%x=%s:%i)\r\n", (unsigned int)calladdr, callsym->name, (int)((ptrdiff_t)calladdr - (ptrdiff_t)callsym->addr));
        /* Get the forward chain */
        KeDebugPrint("%p\r\n", (unsigned int)frame);
        frame = *((uint8_t **)(&frame[8]));
    return 0;
Personal tools