汇编intel x86生成声音

时间:2017-03-24 13:09:21

标签: audio assembly segmentation-fault

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

    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运行它时,它会被分段错误杀死。

通过进一步的研究,我发现在现代操作系统中,由于权利而更难以访问扬声器。如果有人知道如何访问扬声器并播放声音,我很乐意学习它。

注意:当我以超级用户身份运行我的代码时,我没有出现分段错误,但没有声音产生。

1 个答案:

答案 0 :(得分:1)

[在您与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,因为那里的返回权将从代码中跳出,您称之为调用它的地方不再运行代码了: / p>

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的一些技巧,这是一个文档齐全的开源操作系统,可以帮助初学者学习汇编。

希望这会有所帮助!

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