关于内联汇编#bug#的问题,如何解决?

我在写中断函数时出现的问题

void ki(){
    __asm{
        PUSH    ES
        PUSH    DS
        PUSHAD
        MOV        EAX,ESP
        PUSH    EAX
        MOV        AX,SS
        MOV        DS,AX
        MOV        ES,AX
        main:
                mov al,0x61
                out 0xa0,al
                in al,0x60
                mov bx,[0xd0000]
                cmp bx,32
                jae m2
                jmp m3
        m2:
                mov word[0xd0000] ,0
        m3:
                mov [0xd0000+ebx+1],al
                add bx,1
                mov word[0xd0000] ,bx
        POP        EAX
        POPAD
        POP        DS
        POP        ES
        IRETD
    }
    //return;
}
void mi(){
    __asm{
        PUSH    ES
        PUSH    DS
        PUSHAD
        MOV        EAX,ESP
        PUSH    EAX
        MOV        AX,SS
        MOV        DS,AX
        MOV        ES,AX
        main4:
                mov al,0x64
                out 0xa0,al
                mov al,0x62
                out 0x20,al
                nop
                in eax,0x60
                mov bx,[0xd0022]
                cmp bx,512
                jae m5
                jmp m6
        m5:
                mov word[0xd0022] ,0
        m6:
                mov dword[0xd0022+ebx+2] ,eax
                add bx,4
                mov word[0xd0022] ,bx
        POP        EAX
        POPAD
        POP        DS
        POP        ES
        iretd
    }
    //return;
}

img

我用的是cl编译器,希望网上帮忙解决这个bug!

【以下回答由 ChatGPT 生成】

回答

这个问题出现的原因是在使用内联汇编时,编译器无法正确识别其中的标号。解决这个问题可以通过以下步骤:

  1. 使用__asm__关键字替换__asm,这是因为gcc编译器要求使用双下划线作为前缀。
  2. 修改标号的命名方式,将标号前面添加一个%字符,这样编译器可以正确地识别标号。
  3. 修改基地址的定义和访问方式,将起始地址改为一个数组,并使用数组的下标作为偏移量,这样可以使编译器正确地生成汇编代码。

修改后的代码如下所示:

void ki(){
    __asm__ __volatile__ (
        "push %%es\n\t"
        "push %%ds\n\t"
        "pusha\n\t"
        "movl %%esp, %%eax\n\t"
        "push %%eax\n\t"
        "movw %%ss, %%ax\n\t"
        "movw %%ax, %%ds\n\t"
        "movw %%ax, %%es\n\t"
        "main:\n\t"
            "movb $0x61, %%al\n\t"
            "outb %%al, $0xa0\n\t"
            "inb $0x60, %%al\n\t"
            "movw 0xd0000(, %%ebx, 2), %%bx\n\t"
            "cmp %%bx, $32\n\t"
            "jae m2\n\t"
            "jmp m3\n\t"
        "m2:\n\t"
            "movw $0, 0xd0000\n\t"
        "m3:\n\t"
            "movb %%al, 0xd0000(%%ebx)\n\t"
            "inc %%bx\n\t"
            "movw %%bx, 0xd0000\n\t"
        "pop %%eax\n\t"
        "popa\n\t"
        "pop %%ds\n\t"
        "pop %%es\n\t"
        "iret"
    );
}

void mi(){
    __asm__ __volatile__ (
        "push %%es\n\t"
        "push %%ds\n\t"
        "pusha\n\t"
        "movl %%esp, %%eax\n\t"
        "push %%eax\n\t"
        "movw %%ss, %%ax\n\t"
        "movw %%ax, %%ds\n\t"
        "movw %%ax, %%es\n\t"
        "main4:\n\t"
            "movb $0x64, %%al\n\t"
            "outb %%al, $0xa0\n\t"
            "movb $0x62, %%al\n\t"
            "outb %%al, $0x20\n\t"
            "nop\n\t"
            "inl $0x60, %%eax\n\t"
            "movw 0xd0022(, %%ebx, 4), %%bx\n\t"
            "cmp %%bx, $512\n\t"
            "jae m5\n\t"
            "jmp m6\n\t"
        "m5:\n\t"
            "movw $0, 0xd0022\n\t"
        "m6:\n\t"
            "movl %%eax, 0xd0022(%%ebx)\n\t"
            "add $4, %%ebx\n\t"
            "movw %%bx, 0xd0022\n\t"
        "pop %%eax\n\t"
        "popa\n\t"
        "pop %%ds\n\t"
        "pop %%es\n\t"
        "iret"
    );
}

注意上述代码使用的是AT&T语法,即操作数顺序为源操作数在前,目的操作数在后,并且寄存器名前有一个%字符。

请问还有其他问题需要我解决吗?



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

你这个到底是什么汇编,感觉一会儿是16bit的,一会儿是32bit的,而且你这个是vc++的,gcc得用 at&t 格式的汇编