No interruption process



  • Why does this code, which changes the keyboard processor, not work on a real computer (removes the symbol 'A' only once), even though it works normally in bochs and qemu emulators? A compiler gcc, architecture x86.

    asm(".code16gcc\n");
    

    typedef unsigned char uchar;
    typedef unsigned short ushort;
    typedef unsigned int uint;
    typedef struct attribute((packed)) FullAddr{
    ushort offset;
    ushort seg;
    } FullAddr;

    #define MAIN_CODE_START 0x9200

    asm (
    "xorw %ax, %ax\n\t"
    "movw %ax, %ds\n\t"
    /По этому адресу компоновщик помещает начало секции .data/
    "movw (0x9202), %ax\n\t"
    "movw %ax, %ds\n\t"
    "movw %ax, %ss\n\t"
    "movw $0xFFFB, %sp\n\t"
    "jmp main"
    );

    void print_char(char c){
    asm volatile("int $0x10" : : "a"(0x0E00 | c), "b"(7));
    }

    void get_int_addr(ushort interrupt, FullAddr addr)
    {
    asm volatile(
    "pushw %%ds\n\t"
    "movw %w3, %%ds\n\t"
    "movw (%w2), %w0\n\t"
    "movw 2(%w2), %w1\n\t"
    "popw %%ds"
    : "=c"(addr->offset), "=a"(addr->seg):"b"(interrupt
    4),"a"(0)
    );
    }

    void set_int_addr(ushort interrupt, uint func){
    asm volatile(
    "cli\n\t"
    "pushw %%ds\n\t"
    "movw %w2, %%ds\n\t"
    "movw %w0, (%w1)\n\t"
    "movw %%cs, 2(%w1)\n\t"
    "popw %%ds\n\t"
    "sti"
    : : "c"(func-MAIN_CODE_START), "b"(interrupt*4), "a"(0):
    );
    }

    void wait(uint usec)
    {
    asm volatile("int $0x15": : "a"(0x8600), "c"(usec>>16), "d"(usec&0xFFFF));
    }

    FullAddr addr;

    void handler_func(){
    print_char('A');
    }

    void handler();
    asm(
    "handler:\n\t"
    "pushal\n\t"
    "call handler_func\n\t"
    "popal\n\t"
    "ljmp *addr\n\t"
    "iret\n\t"
    );

    void main(){
    get_int_addr(9, &addr);
    set_int_addr(9, (uint)handler);
    while(1){
    wait(1000);
    }
    }

    Just in case. https://www.dropbox.com/s/y53iwc34avhzoob/ar.zip?dl=0 including the diskette image (maybe someone's gonna start). For compilation, we need to start the files build.sh and build_main.sh.



  • Here. https://stackoverflow.com/a/34490442/2586997 They said that the problem was the importance of the segment. %dswhich may change within the interruption processor 0x15 (function waitBIOS. And at this point, it might work to interrupt the 0x9 that I intercept. In the processor of the latter, the segment is used. %ds (sighs)ljmp *addr) I mean, the transition isn't going to be where it is. Disposition: each time in the function handler change %ds and at the end of the function, return the old. Code:

    void handler();
    asm(
        "handler:\n\t"
        "pushw %ds\n\t"
        "pushal\n\t"
        "xorw %ax, %ax\n\t"
        "movw %ax, %ds\n\t"
        "movw (0x9202), %ax\n\t"
        "movw %ax, %ds\n\t"
        "call handler_func\n\t"
        "pushfw\n\t"
        "lcallw *addr\n\t"
        "popal\n\t"
        "popw %ds\n\t"
        "iretw\n\t"
    );
    



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2