如何在 Linux-Assembler 中发出哔哔声?

Posted

技术标签:

【中文标题】如何在 Linux-Assembler 中发出哔哔声?【英文标题】:How to beep in Linux-Assembler? 【发布时间】:2016-12-15 13:23:29 【问题描述】:

我想在汇编器中发出哔哔声。

喜欢

beep()

这可能吗?

我尝试使用带有 BELL-Symbol 的 sysCall 写入。 但它什么也没做。

我使用 Linux-64-Nasm 汇编器,并且,由于我正在构建编译器,我不想使用 C 库。

section .data
cmp_BLANK: db 0x0a
cmp_interr: db "error, You have typed in a non-Integer Character!", 0x0a
cmp_interrlen: equ $-cmp_interr
cmp_buffer: times 9 db 0x00
cmp_beep: db 0x07

section .bss

section .text
global _start
_start:
call func_main
mov eax, 1
mov ebx, 0
int 80h
func_main:
mov eax, 4
mov ebx, 1
mov ecx, cmp_beep
mov edx, 1
int 80h
ret        

但我没有听到声音。即使我使用 sudo 运行它。

【问题讨论】:

仅供参考,这是 32 位代码。至于是否发出哔哔声,取决于使用的终端、X11 中是否启用了铃声(如果您在其下运行)、您的声音模块等情况。 由于哔哔声需要硬件访问,您的问题基本上是this one的重复。 no 不是,因为我没有得到很好的答案。在汇编程序中我不能使用 \a 序列 @Linuxer4Fun 当然不是完全重复的。 Here 你可以找到beep 程序的源代码。该程序非常简单,您可以使用它来创建您的汇编程序。正如我所说,您必须使用操作系统来发出哔声,因为无法从用户空间访问 8254。替代方案:做 LKM。 如果您的终端配置为在程序打印\a 时发出蜂鸣声,那么您只需要这样做。 (请参阅unix.stackexchange.com/questions/1974/… 了解更多关于使用 PC 扬声器实现这一点的信息。在现代终端仿真器(如 konsole 或 gnome-terminal)中,检查配置选项以通过普通扬声器播放声音)。请注意,在 NASM 中,您可以在反引号内使用 C 样式的反斜杠转义,但不能在单引号或双引号中使用。 【参考方案1】:

好的,首先这是一个参考文档:http://www.cs.binghamton.edu/~reckert/220/8254_timer.html

以 C 实现为例:https://github.com/torvalds/linux/blob/master/drivers/input/misc/pcspkr.c#L49

这是 GNU asm 中的哔声代码:

    # send "set tune" command
    movb    $0xB6, %al
    outb    %al, $0x43

    # nanosleep to let the IO complete                                                                                                                                  
    movl    $0x1000, %eax
1:  subl    $1, %eax
    cmpl    $0, %eax
    jne     1b

    # set 220Hz, 0x152F == 1193180 / 220
    movb    $0x2F, %al
    outb    %al, $0x42

    # nanosleep
    movl    $0x1000, %eax
1:  subl    $1, %eax
    cmpl    $0, %eax
    jne     1b

    movb    $0x15, %al
    outb    %al, $0x42

    # nanosleep
    movl    $0x1000, %eax
1:  subl    $1, %eax
    cmpl    $0, %eax
    jne     1b

    # turn on the speaker
    inb     $0x61, %al
    movb    %al, %ah
    orb     $0x3, %al
    outb    %al, $0x61

    # sleep about 1 sec
    movl    $0x30000000, %eax
1:  subl    $1, %eax
    cmpl    $0, %eax
    jne     1b

    # turn off the speaker
    movb    %ah, %al
    andb    $0xfc, %al
    outb    %al, $0x61

此代码不会立即在用户空间程序中运行,因为内核禁止写入 IO 端口。为了允许该代码还需要 ioperm 调用:ioperm(0x42, 32, 1) 并使用 sudo 运行。请参阅gist 中的完整工作示例。

【讨论】:

以上是关于如何在 Linux-Assembler 中发出哔哔声?的主要内容,如果未能解决你的问题,请参考以下文章

Layered Microservices Architecture | 雷达哔哔哔

雷达哔哔哔 - Layered Microservices Architecture

爬虫使用线程池爬取哔哩哔哩数据,只能打印出一页的数据,加了锁也不行,如何修改呢?

默认“哔哔”闹钟铃声

大数据哔哔集20210111HDFS中的常用压缩算法及区别

盈利难,大V惹事端 哔哩哔哩社区生态遭挑战