以下代码是我尝试将内容从一个数组复制到另一个数组。但由于某种原因它不起作用。有人可以帮我这个吗?
;copy frequency array to calculation array
lea dx,frequency
lea ax,array
mov cx,512
address:
mov bx, dx
mov ax, bx
inc dx
inc ax
loop address
答案 0 :(得分:2)
对于移动字符串,x86 string instructions可以是一种很好的方法。 x86字符串指令使用ds:si
和es:di
段和偏移寄存器组合在存储器和累加器ax
之间或两个存储器位置之间进行字节或字移动。与repnz
结合使用可以得到一个紧凑的解决方案:
lds si, frequency ; ds:si contains frequency pointer
les di, array ; es:di contains array pointer
mov cx, 512 ; how many bytes to move
shr cx, 1 ; how many words to move
cld ; clear direction bit to auto increment pointers on data moves
repnz movsw ; move cx words from ds:si to es:di
repnz
将重复下一个字符串指令(在本例中为movsw
),在每次执行后递减cx
,直到cx
变为零。单个movsw
执行将一个字(2个字节)从ds:si
指向的位置移动到位置es:di
,并在{2}后逐个递增si
和di
一举一动。从cld
清除的方向位确保在si
和di
上完成增量,而如果设置方向位(std
),则这些指针寄存器将减少
我假设您的512是字节数。但是,如果它开头一个字数,那么显然你不会做我上面显示的shr cx,1
。
x86字符串指令支持字节,字和双字操作。
答案 1 :(得分:1)
这是修复后的代码,解释如下:
;copy frequency array to calculation array
lea si, frequency ;SI = POINTER TO FREQUENCY.
lea di, array ;DI = POINTER TO ARRAY.
mov cx, 512 ;COUNTER.
address:
mov ax, [ si ] ;GET TWO BYTES FROM FREQUENCY.
mov [ di ], ax ;PUT TWO BYTES INTO ARRAY.
add si, 2 ;NEXT TWO BYTES IN FREQUENCY.
add di, 2 ;NEXT TWO BYTES IN ARRAY.
sub cx, 2 ;COUNTER-2.
jnz address ;IF ( COUNTER != 0 ) REPEAT.
DX由SI和AX改变为DI,因为DX和AX不能用作指针,不允许执行 [ax] 或 [dx] 。 SI和DI本质上是指针,它们的名称是“源索引”和“目标索引”,因此它们可以用作 [si] 和 [di] 。了解 SI 和 [SI] 之间的区别非常重要:第一个是地址,第二个是地址的内容。
SI,DI和CX递增/递减2,因为我们不移动字节而是移动字(两个字节)。这种方式更快。</ p>
最后,最好避免使用像“地址”这样的词,因为它们可能是保留字。