使用OUT指令在旧版PC扬声器上产生声音

问题描述 投票:0回答:1

我目前正在尝试在汇编代码中生成声音。这是我发现的一些代码:

    section .text
  global sound

sound:
    mov     al, 182         ; meaning that we're about to load
    mov     ax, 182
    out     43h, al         ; a new countdown value
    ret
    mov     ax, 2153        ; countdown value is stored in ax. It is calculated by 
    out     42h, al         ; Output low byte.
    mov     al, ah          ; Output high byte.
    out     42h, al               

    in      al, 61h         
    or      al, 00000011b  
    out     61h, al     ; Send the new value
    ret

根据此代码的所有者,它应该可以工作,但是当我使用C main运行它时,它被分段错误杀死。

[通过进一步的研究,我发现在现代操作系统中,由于权限的原因,很难访问发言人。如果有人知道如何使用扬声器并播放声音,我很乐意学习。

注意:当我以超级用户身份运行代码时,没有任何分割错误,但是没有声音。

assembly audio x86 segmentation-fault pc
1个回答
0
投票

[[在使用NASM编译器阅读本著作之前,我不确定其他编译器是否有用]

您的代码很好,但这是问题所在:

  1. 它不会在虚拟机中产生声音。0x43、0x42端口用于的是PIT(可编程间隔定时器)芯片,该芯片处理的内容可在此处OSDEVWIKI上阅读。 PIT芯片处理的事情之一是板载扬声器,这是您尝试访问的扬声器。虚拟机没有板载扬声器。

长话短说,您正在尝试访问主板扬声器,但虚拟机无法使用它,因此您听不到任何声音。

而且大多数较新的主板也没有板载扬声器。

  1. 您的代码。因此,从您的代码看一眼,我猜您正在使用nasm,因此对此我有些困惑:
mov     al, 182         ; meaning that we're about to load
mov     ax, 182
out     43h, al         ; a new countdown value
ret

要稍微修饰一下此部分,您可以删除mov ax, 182ret,因为那里的返回权将跳出代码,直到您调用它的位置不再运行代码:

mov     ax, 2153        ; countdown value is stored in ax. It is calculated by 
out     42h, al         ; Output low byte.
mov     al, ah          ; Output high byte.
out     42h, al               

in      al, 61h         
or      al, 00000011b  
out     61h, al     ; Send the new value
ret

已过时。对于mov ax, 182,当我使用免提扬声器时,它的工作原理与此无关,所以我想您不需要它,因此,如果需要,我说将其删除。

因此,您的代码的修订版将是:

bits 16

start:
mov ax, 0x07c0   ; Setup the stack past where we are loaded
add ax, 544
cli              ; Disable interrupts
mov ss, ax
mov sp, 4096
sti              ; Restore interrupts

mov ax, 0x07c0   ; Set the data segment to where we are
mov ds, ax

sound:
mov al, 182         ; Were about to load
out 0x43, al

mov ax, 15000       ; 15000(Pitch) = 1,193,180 / 79.5453333(Repeating)

out 0x42, al        ; Give the port the lower value
mov al, ah
out 0x42, al        ; Now give it the higher

in al, 0x61         

or al, 00000011b    ; Connect the speaker to Timer 2
out 0x61, al
jmp $               ; hang

times 510-($-$$) db 0     ; Pad the rest of the file with 0's
dw 0xaa55                 ; Little Endian MBR Signature

要运行此程序以查看其是否有效,请确保您的计算机装有板载扬声器。我的看起来像这样:here

如果没有它,您的外观可能不像我的,如果没有,您可以在代码后显示或使某些事情发生以确保其运行。

我使用这些命令来运行它。

nasm -f bin <YOURFILENAME>.asm -o boot.bin
dd if=boot.bin of=\\.\<DRIVENUMBER>: bs=512

这些是nasm,一个是nasm编译器,用于编译程序集文件。如果您在linux上,dd已经是rawwrite了,但是在像我正在使用的Windows上,您可以下载rawwrite here。确保您的驱动器号是您正在使用的驱动器,例如USB或FLOPPY。例如,如果您的USB位于驱动器d上:您将使用:dd if=boot.bin of=\\.\d: bs=512

然后,您可以将USB与振荡器一起插入计算机。为我启动计算机并进入启动菜单,我只是向其发送垃圾邮件f10,直到到达那里为止,但是对于您来说,它可能是一个不同的按钮,系统将询问您应引导哪个设备来找到USB并启动它。如果没有操作系统显示,它将启动:

mov ah, 0x0e
mov al, 'X'
int 0x10

要查看是否正在启动,请在bits 16之后将其添加到文件顶部:

jmp short start
nop

OEMLabel            db "Contoso"   ; OEM Label
BytesPerSector      dw 512          ; There are 512b per sector
SectorsPerCluster   db 1            ; Sectors per cluster
ReservedForBoot     dw 1            ; # of sectors reserved for boot
NumberOfFats        db 2            ; # of fats
RootDirEntries      dw 224          ; # of root directory entries
LogicalSectors      dw 2880         ; # of sectors
MediumByte          db 0x0f0        ; Medium descriptor byte
SectorsPerFat       dw 9            ; # of sectors per fat
SectorsPerTrack     dw 18           ; # of sectors per track
Sides               dw 2            ; # of sides
HiddenSectors       dd 0            ; # of hidden sectors
LargeSectors        dd 0            ; # of large sectors
DriveNo             dw 0            ; The drive number
Signature           db 41           ; The drive signature
VolumeID            dd 0xdeadbeef   ; The volume id
VolumeLabel         db "Windows9   "; This can be any 11 characters
FileSystem          db "FAT12   "   ; File system of the floppy DONT CHANGE

如果由于某种原因该代码不起作用,请检查是否有任何错误,并确保您的主板有板载扬声器。

有关更多信息,请按上述here。源代码here的基础。有关汇编here的一些技巧,这是一个文档齐全的开源OS,可以帮助初学者学习汇编。

希望这会有所帮助!

编辑:一些错别字和彼得·科德斯的帮助(在评论中)

© www.soinside.com 2019 - 2024. All rights reserved.