是的,有专门为此设计的说明。
不过,它确实需要一些设置。
cld //CLear the Direction flag (optional, see below)
mov al,10 //we are moving bytes
mov edi,MemAddrStart //Destination = start
mov ecx,(MemAddrEnd - MemAddrStart)+ 1 //Count = (end-start)+1
rep stosb //(REP)repeat (STOS)storing (B)bytes until done
请参阅:STOSB documentation。
方向标志
The direction flag 确定rep stosx 是向前还是向后移动。
您应该始终让它继续前进,因为这是默认方向。
如果您使用std 将其设置为向后,请确保之后使用cld 将其重置为正常状态。如果不这样做,可能会发生坏事,因为许多编译器和操作系统都假定方向标志始终是明确的。
'[...] 如果没有,我该怎么办?'
你当然可以使用一个简单的循环来编程:
mov al,10 //we are moving bytes
mov edi,MemAddrStart //destination = start
mov ecx,(MemAddrEnd - MemAddrStart)+ 1 //length = (end-start)+1
Loop:
dec ecx //This is
mov [edi+ecx],al //what `rep stosb`
jnz Loop //does
请注意,为了提高效率和简单性,我的循环从最后开始并返回。 stos(清除方向标志)从头开始。否则,两者的工作方式相同。
因为我正在减少ecx,所以我可以使用零的隐式测试 (jnz),并且不需要添加另一个测试或另一个寄存器来查看我是否完成了。
示例代码备注
mov ax, 10
mov [memAddrStart to MemAddrEnd], ax
此代码移动一个字(16 位)。这会写入字节
Address HEX DEC
MemAddrStart: 0A 10
MemAddrStart+1: 00 00
如果您在循环中执行以下操作,请记住,而不是您想要的:
dec ecx
mov [edi+ecx],ax
jnz Loop
您将编写以下内容:
Address HEX DEC
MemAddrStart: 0A 10
MemAddrStart+1: 0A 10
....
MemAddrEnd 0A 10
MemAddrEnd+1 00 00 <<-- Oops, you're writing past the buffer.
这被称为a buffer overflow,这是一个可能导致各种令人讨厌的问题的错误。
如果您想存储单词,那么您必须更改您的代码才能这样做。(mov ecx,(end-start+1)/2rep stosw)。