尝试了解 asm 中断,特别是 16h func 01H

2024-03-01

这是家庭作业,我不期望你解决我的问题,只需要一些理解......

我必须在 dosbox 中使用 ASM 和 C。我的第一个问题是我不太明白如何使用 BIOS 中断(任何带有代码示例的好的教程都会非常感激),好吧,我知道有中断,每个中断都有自己的功能和参数......

不管怎样,我已经尝试过......理论上,我需要做的很简单,我只需要从键盘获取一个字符,如果它是 1 或 0 键,则数一下,如果我有 5 次按键 1,我打开扬声器,如果扬声器打开并且我有三个0键,则扬声器关闭,如果鼠标向右移动也可以关闭......

我几乎已经完成了,我的问题是从中断中获取返回的字节并检查它。

为了获取字符,我使用 INT 16H 中的函数 01H,这就是为什么我不希望 asm 块等到新字符出现为止,问题是我无法理解如何获取零标志来告诉我如果新字符已到达,如果是,则获取它并将其从键盘缓冲区中删除。

这是我的循环:

// Loop
for(;;) {
        initTimer();

        if (key == ESC) break; // If ESC is pressed...

        if (mouseExist == TRUE) currentX = getMouseX(); // Mouse X position

        /* In that block I wait for the user input, it works...
        asm {
            mov AH, 08H  
            int 21H     // DOS-API
            mov key, AL

        }
        */
            // Block I don't get...UPDATED
        asm {
            mov ah, 01H
            int 16h
                    jz not_set // If zero flag is 1, jump to not_set, else
            mov key, al // Getting key
                    mov ah, 04H  // reset buffer
                    int 16H

        }
            not_set:
            // Count ones
        if (key == ONE && countOnes < MAX_ONES) {
            countOnes++;
            resetBuffer(); // Reset keyboard buffer (NOT WORKING)...
        }
        // Count 0s
        else if (key == ZERO && isPlaying == TRUE) countZeros++;

        // If I have enought zeros OR speaker is on AND mouse have been moved to            
            // the right 
        if (countZeros == MAX_ZERO || (initX < currentX && isPlaying == TRUE)) {
            stop(); // Stop speaker...It works...
            // Restore counters
            countOnes = 0;
            countZeros = 0;
            checkMouse(); // Reset Mouse...Works...
            showMouse(); // Works
            initX = getMouseX();
                currentX = initX;
            isPlaying = FALSE;
        } else if (countOnes == MAX_ONES) { // I have the ones
            isPlaying = TRUE;
            play(); // Turn on the speaker.
        }
            key = '\0';
           // I have also try to reset buffer here...No luck...
           //resetBuffer()
    }

函数重置缓冲区:

void resetBuffer() {
    asm {
        mov AH, 04H // Function reset
        int 16H
    }
}

提前致谢...


您可以压入标志,然后将它们弹出到寄存器中以检查相应的位:

unsigned short flags;
asm {
    mov ah, 04h
    int 16h
    pushf
    pop ax
    mov flags, ax
}
if (flags & 0x40) {
    // zero flag is set
}

您还可以直接在汇编中检查标志:

    mov ah, 04h
    int 16h
    jz not_set
    // here, if zero flag was set
not_set:

标签的确切语法取决于您的编译器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试了解 asm 中断,特别是 16h func 01H 的相关文章

随机推荐