问题描述
我想使用 si 寄存器循环遍历一系列持续时间数字。但这并不适合我。如果我仅传递一个数字 dur ,那么它工作正常,如果我要进行迭代,则它会冻结并且没有其他内容。解释错误。谢谢!
sseg segment stack
db 256 dup(?)
sseg ends
dseg segment
music dw 4063,2559,3835
duration dd 270000,360000,180000
dur dd 270000
len dw 3
dseg ends
cseg segment
assume ss:sseg,cs:cseg,ds:dseg
start: jmp main
main: push ds
xor ax,ax
push ax
mov ax,dseg
mov ds,ax
cli
;------------------------------
xor di,di
xor si,si
cycle:
mov al,10110110b
out 43h,al
in al,61h
or al,3
out 61h,al
;------------
mov ax,music[si]
out 42h,al
mov al,ah
out 42h,al
les dx,dur ;duratin[si]
mov cx,es
mov ah,86h
int 15h
;------------
in al,61h
and al,11111100b
out 61h,al
;------------
inc si
inc di
cmp si,len
jnae cycle
;------------------------------
exit:
sti
mov ax,4c00h
int 21h
cseg ends
end start
解决方法
mov ax,music[si]
在接下来的讨论中,MASM是否允许music[si]
或[music+si]
都不重要。
重要的一点是SI
寄存器不是像我们从高级语言中知道的那样的数组索引,而是它是从数组开头的偏移量,始终以字节为单位。
因此,在您的程序中,您需要向寻址 music 数组(单词)的寄存器添加2,并且需要向寻址 duration 数组的寄存器添加4( dwords)。
music dw 4063,2559,3835
duration dd 270000,360000,180000
len = $-offset duration
...
xor di,di ; Offset in duration array
xor si,si ; Offset in music array
cycle:
...
mov ax,music[si]
...
les dx,duration[di] ; This is DI,beware of your typo
mov cx,es
mov ah,86h
int 15h
...
add si,2 ; To next music item (word=2)
add di,4 ; To next duration item (dword=4)
cmp di,len
jb cycle