是否可以将同一字节快速移至一堆地址
pseudocode...
mov ax, 10
mov [memAddrStart to MemAddrEnd], ax
这会将AX放入每个地址中,因此我可以引用序列中的任何地址并始终获取10。
这有可能吗?如果没有,我该如何解决?
答案 0 :(得分:4)
是的,有专门为此设计的说明。
虽然确实需要一些设置。
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)/2
rep stosw
)。