使用汇编代码播放音乐
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用汇编代码播放音乐相关的知识,希望对你有一定的参考价值。
我正在做一个实验室项目,我遇到了一个小问题。我已经写了一些代码来制作音符,这部分似乎有效。我遇到的问题是我处理音乐的'm'键,当我按下它时,音乐会播放,就像它应该的那样。但是,我需要处理另一个键或按钮以暂停音乐,再次按下时,(第二次)音乐应该继续播放,就在它停止的地方。我真的无法弄清楚如何处理第二次按键,所以音乐将继续,而不是重新开始。我在GUI Turbo Assembler工作,这是我到目前为止的代码的核心:
TITLE MUSIC.EXE
STACKSG SEGMENT PARA STACK 'Stack'
DW 128 DUP(?)
STACKSG ENDS
DATASG SEGMENT PARA 'Data'
DATASG ENDS
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG, DS:DATASG, SS:STACKSG, ES:NOTHING
SOUND PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV AL, 0B6H
OUT 43H, AL
MOV DX, 14H
MOV AX, 4F38H
DIV DI
OUT 42H, AL
MOV AL, AH
OUT 42H, AL
IN AL, 61H
MOV AH, AL
OR AL, 3
OUT 61H, AL
L1: MOV CX, 6801
L2: LOOP L2
DEC BX
JNZ L1
MOV AL, AH
OUT 61H, AL
POP DI
POP DX
POP CX
POP BX
POP AX
RET
SOUND ENDP
MAIN PROC
MOV BX, 50
L3: MOV AH, 0
INT 16H
CMP AL, 'x'
JE EXIT
CMP AL, 'q'
JE DO
CMP AL, 'w'
JE RE
CMP AL, 'e'
JE MI
CMP AL, 'r'
JE FA
CMP AL, 't'
JE SOL
CMP AL, 'y'
JE LA
CMP AL, 'u'
JE CI
CMP AL, 'm'
JE MEL
JNZ L3
DO: MOV DI, 131
CALL SOUND
JMP L3
RE: MOV DI, 147
CALL SOUND
JMP L3
MI: MOV DI, 165
CALL SOUND
JMP L3
FA: MOV DI, 175
CALL SOUND
JMP L3
SOL: MOV DI, 196
CALL SOUND
JMP L3
LA: MOV DI, 220
CALL SOUND
JMP L3
CI: MOV DI, 247
CALL SOUND
JMP L3
EXIT: MOV AH, 00H
MOV AL, 03H
INT 10H
MOV AX, 4C00H
INT 21H
RET
MEL:
L4: LOOP L4
MOV DI, 147
CALL SOUND
MOV DI, 147
CALL SOUND
MOV DI, 147
CALL SOUND
MOV DI, 196
CALL SOUND
MOV DI, 196
CALL SOUND
MOV DI, 175
CALL SOUND
MOV DI, 165
CALL SOUND
MOV DI, 220
CALL SOUND
MOV DI, 220
CALL SOUND
MOV DI, 196
CALL SOUND
MOV DI, 147
CALL SOUND
MOV DI, 147
CALL SOUND
MOV DI, 147
CALL SOUND
MOV DI, 147
CALL SOUND
JMP L4
MAIN ENDP
CODESG ENDS
END MAIN
答案
大家,新年快乐!
; Name: music.asm
; Assemble: tasm.exe music.asm
; Link: tlink.exe music.obj
; Run in DOSBox: music.exe
a0 = 43388 ; 27.5000 hz
ais0 = 40953 ; 29.1353 hz
h0 = 38655 ; 30.8677 hz
c1 = 36485 ; 32.7032 hz
cis1 = 34437 ; 34.6479 hz
d1 = 32505 ; 36.7081 hz
dis1 = 30680 ; 38.8909 hz
e1 = 28958 ; 41.2035 hz
f1 = 27333 ; 43.6536 hz
fis1 = 25799 ; 46.2493 hz
g1 = 24351 ; 48.9995 hz
gis1 = 22984 ; 51.9130 hz
a1 = 21694 ; 55.0000 hz
ais1 = 20477 ; 58.2705 hz
h1 = 19327 ; 61.7354 hz
c2 = 18243 ; 65.4064 hz
cis2 = 17219 ; 69.2957 hz
d2 = 16252 ; 73.4162 hz
dis2 = 15340 ; 77.7817 hz
e2 = 14479 ; 82.4069 hz
f2 = 13666 ; 87.3071 hz
fis2 = 12899 ; 92.4986 hz
g2 = 12175 ; 97.9989 hz
gis2 = 11492 ; 103.8260 hz
a2 = 10847 ; 110.0000 hz
ais2 = 10238 ; 116.5410 hz
h2 = 9664 ; 123.4710 hz
c3 = 9121 ; 130.8130 hz
cis3 = 8609 ; 138.5910 hz
d3 = 8126 ; 146.8320 hz
dis3 = 7670 ; 155.5630 hz
e3 = 7240 ; 164.8140 hz
f3 = 6833 ; 174.6140 hz
fis3 = 6450 ; 184.9970 hz
g3 = 6088 ; 195.9980 hz
gis3 = 5746 ; 207.6520 hz
a3 = 5424 ; 220.0000 hz
ais3 = 5119 ; 233.0820 hz
h3 = 4832 ; 246.9420 hz
c4 = 4561 ; 261.6260 hz
cis4 = 4305 ; 277.1830 hz
d4 = 4063 ; 293.6650 hz
dis4 = 3835 ; 311.1270 hz
e4 = 3620 ; 329.6280 hz
f4 = 3417 ; 349.2280 hz
fis4 = 3225 ; 369.9940 hz
g4 = 3044 ; 391.9950 hz
gis4 = 2873 ; 415.3050 hz
a4 = 2712 ; 440.0000 hz
ais4 = 2560 ; 466.1640 hz
h4 = 2416 ; 493.8830 hz
c5 = 2280 ; 523.2510 hz
cis5 = 2152 ; 554.3650 hz
d5 = 2032 ; 587.3300 hz
dis5 = 1918 ; 622.2540 hz
e5 = 1810 ; 659.2550 hz
f5 = 1708 ; 698.4560 hz
fis5 = 1612 ; 739.9890 hz
g5 = 1522 ; 783.9910 hz
gis5 = 1437 ; 830.6090 hz
a5 = 1356 ; 880.0000 hz
ais5 = 1280 ; 932.3280 hz
h5 = 1208 ; 987.7670 hz
c6 = 1140 ; 1046.5000 hz
cis6 = 1076 ; 1108.7300 hz
d6 = 1016 ; 1174.6600 hz
dis6 = 959 ; 1244.5100 hz
e6 = 905 ; 1318.5100 hz
f6 = 854 ; 1396.9100 hz
fis6 = 806 ; 1479.9800 hz
g6 = 761 ; 1567.9800 hz
gis6 = 718 ; 1661.2200 hz
a6 = 678 ; 1760.0000 hz
ais6 = 640 ; 1864.6600 hz
h6 = 604 ; 1975.5300 hz
c7 = 570 ; 2093.0000 hz
cis7 = 538 ; 2217.4600 hz
d7 = 508 ; 2349.3200 hz
dis7 = 479 ; 2489.0200 hz
e7 = 452 ; 2637.0200 hz
f7 = 427 ; 2793.8300 hz
fis7 = 403 ; 2959.9600 hz
g7 = 380 ; 3135.9600 hz
gis7 = 359 ; 3322.4400 hz
a7 = 339 ; 3520.0000 hz
ais7 = 320 ; 3729.3100 hz
h7 = 302 ; 3951.0700 hz
c8 = 285 ; 4186.0100 hz
whole_note = 1800
half_note_dot = whole_note/2 + whole_note/4
half_note = whole_note/2
quarter_note_dot = whole_note/4 + whole_note/8
quarter_note = whole_note/4
eighth_note = whole_note/8
pause = 30
LOCALS
.MODEL SMALL
.STACK
.DATA
div1 dd 14318180
div2 dd 786432000
AuldLangSyne dw 0,eighth_note
dw g3,quarter_note
dw c4,quarter_note_dot,h3,eighth_note,c4,quarter_note,e4,quarter_note
dw d4,quarter_note_dot,c4,eighth_note,d4,quarter_note,e4,eighth_note,d4,eighth_note
dw c4,quarter_note,0,pause,c4,quarter_note,e4,quarter_note,g4,quarter_note
dw a4,half_note_dot,0,pause,a4,quarter_note
dw g4,quarter_note_dot,e4,eighth_note,0,pause,e4,quarter_note,c4,quarter_note
dw d4,quarter_note_dot,c4,eighth_note,d4,quarter_note,e4,eighth_note,d4,eighth_note
dw c4,quarter_note_dot,a3,eighth_note,0,pause,a3,quarter_note,g3,quarter_note
dw c4,half_note_dot,0,quarter_note,a4,quarter_note
dw g4,quarter_note_dot,e4,eighth_note,0,pause,e4,quarter_note,c4,quarter_note
dw d4,quarter_note_dot,c4,eighth_note,d4,quarter_note,a4,quarter_note
dw g4,quarter_note_dot,e4,eighth_note,0,pause,e4,quarter_note,g4,quarter_note
dw a4,half_note_dot,0,pause,a4,quarter_note
dw g4,quarter_note_dot,e4,eighth_note,0,pause,e4,quarter_note,c4,quarter_note
dw d4,quarter_note_dot,c4,eighth_note,d4,quarter_note,e4,eighth_note,d4,eighth_note
dw c4,quarter_note_dot,a3,eighth_note,0,pause,a3,quarter_note,g3,quarter_note
dw c4,half_note_dot
dw 0,0
Welcome db "[p] Pause (any key for resuming) [r] Restart [x] Exit $"
.CODE
.486
delay PROC NEAR ms:word ; ARG on stack: delay in ms (granularity ~55 ms)
push bp
mov bp, sp
sub sp, 4
xor ax, ax
mov es, ax
mov edx, es:[046Ch]
; Ticks/sec: 14318180 / 12 / 65536 = 18.206785178403397675542331069912 -> 54.9254 mS
fild word ptr ms
fimul dword ptr div1
fidiv dword ptr div2
fistp dword ptr [bp-4]
add edx, [bp-4]
@@L1:
mov eax, es:[046Ch]
cmp eax, edx
jb @@L1
leave
ret 2
delay ENDP
play PROC NEAR ; ARG si: pointer to freq/duration pairs, end with 0/0
mov di, si ; Preserve it for the check_key routine
@@L1:
cmp word ptr [si], 0 ; No tone?
je @@J1 ; Yes: skip the sound blocks, just delay
; Set up frequency
cli ; Don't disturb the setting sequence
mov al, 0B6h
out 43h, al
mov ax, [si]
out 42h, al
mov al, ah
out 42h, al
sti
in al, 61h ; Speaker on
or al, 03h
out 61h, al
@@J1:
push word ptr [si+2] ; Hold the tone for a certain while
call delay
in al, 61h ; Speaker off
and al, 0FCh
out 61h, al
add si, 4
call check_key ; DI: pointer for restart
cmp word ptr [si+2], 0
jne @@L1
ret
play ENDP
check_key PROC ; ARG di: pointer for restart
mov ah, 1 ; Check keyboard
int 16h
jz @@done ; No key -> return
mov ah, 0 ; Get key
int 16h
@@K0: ; Pause
cmp al, 'p'
jne @@K1
call @@pause
@@K1:
cmp al, 'P'
jne @@K2
@@pause:
mov ah, 0
int 16h
push eighth_note
call delay
jmp @@K0
@@K2: ; Exit
cmp al, 'x'
je @@exit
cmp al, 'X'
jne @@K3
@@exit:
mov ax, 4C00h
int 21h
@@K3: ; Restart
cmp al, 'r'
je @@restart
cmp al, 'R'
jne @@K4
@@restart:
mov si, di
@@K4: ; Placeholder for further key checks
@@done:
ret
check_key ENDP
main PROC
mov ax, @data
mov ds, ax
mov ah, 9
lea dx, Welcome
int 21h
lea si, AuldLangSyne
call play
mov ax, 4C00h
int 21h
main ENDP
END main
另一答案
这样的事情最好的地方是循环L2
:
...
L1: MOV CX, 6801
L2:
push ax ; Preserve AX
mov ah, 1 ; CHECK FOR KEYSTROKE
int 16h
jz done ; No keystroke, no pause
mov ah, 0 ; GET KEYSTROKE
int 16h
cmp al, 'p' ; Key == 'p'?
jnz done ; No -> no action
@J1: ; Loop for pause
pop ax 以上是关于使用汇编代码播放音乐的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段