美文网首页
内联汇编控制PC蜂鸣器

内联汇编控制PC蜂鸣器

作者: 网路元素 | 来源:发表于2019-10-31 07:24 被阅读0次

    有了《初识Linux汇编》和《I/O映射之I/O端口》两篇文章的基础学习后,我们对控制PC蜂鸣器的操作改为使用内联汇编的方法,里面会使用到约束“a”和“dN”,其中前者对应eax,后者对应edx,并且N表示0-255之间的数,有了这些了解后,我们改造下“I/O映射之I/O端口”里的例子,改造后的代码如下:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/moduleparam.h>
    #include <linux/timex.h>

    static int value = 0;
    module_param(value, int, 0644);
    MODULE_PARM_DESC(value, "the beep frequences(20,32767)");

    static __init int ioport_beep_init(void)
    {
            unsigned int count = 0;
            u8 val;
            u16 port;

            if (value > 20 && value < 32767)
                    count = PIT_TICK_RATE / value;

            if (count) {
                    /* set command for counter 2, write 2 bytes */
                    val = 0xB6;
                    port = 0x43;
                    asm volatile("outb %0,%1" : : "a" (val), "dN" (port));

                    /* select desired HZ */
                    val = count & 0xff;
                    port = 0x42;
                    asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
                    val = (count >> 8) & 0xff;
                    asm volatile("outb %0,%1" : : "a" (val), "dN" (port));

                    /* enable counter 2 */
                    port = 0x61;
                    asm volatile("inb %1,%0" : "=a" (val) : "dN" (port));
                    val = val | 3;
                    asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
            } else {
                    /* disable counter 2 */
                    port = 0x61;
                    asm volatile("inb %1,%0" : "=a" (val) : "dN" (port));
                    val = val & 0xFC;
                    asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
            }
            return 0;
    }

    static __exit void ioport_beep_exit(void)
    {
            u8 val;
            u16 port;

            /*disable counter 2 */
            port = 0x61;
            asm volatile("inb %1,%0" : "=a" (val) : "dN" (port));
            val = val & 0xFC;
            asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
            printk("Bye ioport_beep!\n");
    }

    module_init(ioport_beep_init);
    module_exit(ioport_beep_exit);

    MODULE_LICENSE("GPL");

    Makefile文件和源码文件名均未改变,从源码可以看出使用到了汇编的inb和outb指令,其用法也一目了然,这里也不多说了,有空再继续学习改造吧。

    相关文章

      网友评论

          本文标题:内联汇编控制PC蜂鸣器

          本文链接:https://www.haomeiwen.com/subject/kyqryctx.html