【问题标题】:Interrupt handler in ASM/C - How to? -MinixASM/C 中的中断处理程序 - 如何? -Minix
【发布时间】:2014-10-26 18:01:57
【问题描述】:

我一直在 Unix OS、Minix 中对硬件(鼠标、键盘等)进行编程,当被提示将其与 Assembly(AT&T 语法)结合时遇到了一些问题。

到目前为止,我正在对键盘进行编程(获取和打印扫描代码),并且我需要在 C 和 ASM 中进行。我已经开发了正常工作的 C 函数,现在我必须用 ASM 函数替换 IH(中断处理程序),如下代码所示:(要替换的代码在函数“receiver_loop”中)

int timer_subscribe_int(void ) {

    int temp = hook_id; //integer between 0 and 31
    sys_irqsetpolicy(TIMER0_IRQ, IRQ_REENABLE,&hook_id); // returns a hook id that you can then use to enable and disable irqs.
    sys_irqenable(&hook_id);
    return temp;
}

int timer_unsubscribe_int() {

    if (sys_irqrmpolicy(&hook_id)!= OK) return 1;
    return 0;
}


void receiver_loop() {

    int ipc_status,r, seconds = 0, running = 1;
    message msg;

    int shift = keyboard_subscribe_int();
    int shift_timer;
    if(timer_flag) shift_timer = timer_subscribe_int();

        while(running && (seconds < time)) {
            /* Get a request message. */
            if ( driver_receive(ANY, &msg, &ipc_status) != 0 ) {
                printf("driver_receive failed with: %d", r);
                continue;
            }
            if (is_ipc_notify(ipc_status)) { /* received notification */
                switch (_ENDPOINT_P(msg.m_source)) {
                case HARDWARE: /* hardware interrupt notification */
                    if (msg.NOTIFY_ARG & BIT(shift)) { /* subscribed interrupt  bit 1 fica a 1, logo é 1*/

                    // Handle interruption
                     /*Replace the following commented code with ASM function(s)

                        if(keyboard_int_handler()) running = 0;
                        else seconds = 0;

                    }

                    else if (msg.NOTIFY_ARG & BIT(shift_timer) && timer_flag) { // subscribed interrupt  bit 1 fica a 1, logo é 1
                        //printf("\n Entrou aqui. Counter %d \n", counter);
                        timer_int_handler();
                        if (counter%60 == 0){
                            //as the frequency of interruptions is 60Hz as assumed, that means every 60 interrupts 1 second has passed
                            //so whatever is inside this if-block happens each second
                            seconds++; // increments the seconds counter
                            //printf("\n Segundos: %d \n", seconds);
                    };*/
                }
                break;
            default:
                break; /* no other notifications expected: do nothing */
            }
        } else { /* received a standard message, not a notification */
            /* no standard messages expected: do nothing */
        }
    }

    if(seconds >= time) {
        printf("\nTimeout. Terminating...\n");
    }


    keyboard_unsubscribe_int();
    timer_unsubscribe_int();
    return;
}

这是我到目前为止所得到的,老实说,我对如何从这里开始并获得一个类似的 ASM 函数来替换注释代码感到有点困惑。谁能帮我一把?

【问题讨论】:

  • 您的目标是什么 CPU?什么操作系统?
  • 迷你 3.1.8。第一个问题是什么意思?
  • 您使用的是什么处理器?
  • 英特尔® 酷睿™ i7-3610QM
  • 用简单的方法来做怎么样?步骤1)将c中的代码重写为函数(使用__attribute__((noinline)))。步骤 2) 使用 -S 编译以获取 asm 输出。步骤 3) 获取 asm 输出并放入 asm 文件中。

标签: c assembly keyboard interrupt-handling minix


【解决方案1】:

gcc 提供了一种简单的方法来获取您的 c 代码并输出相关的汇编程序。因此,如果您需要将一些 c 代码转换为汇编程序。一个简单的方法如下所示:

  1. 首先将代码本地化为一个例程。
  2. __attribute__((noinline))标记这个例程以防止gcc 从将您的例程内联到其他例程中。虽然平时 内联是一件好事,它可以让你的代码运行得更快,如果你 正在尝试隔离特定代码,这不是您需要的。
  3. 使用如下命令行编译代码:gcc -S -o test.s test.c。请注意,您可以(并且可能应该)打开 优化 (gcc -O2 -S -o test.s test.c)。
  4. test.c 的程序集现在在 test.s 中。检查它以找到您的 例行公事。

请注意,默认情况下,i386 上的输出将采用 att 格式。如果你喜欢intel格式,可以使用-masm=intel

【讨论】:

    猜你喜欢
    • 2012-09-24
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2023-03-08
    • 2013-09-02
    相关资源
    最近更新 更多