将相同的字节移到两个不同地址之间的每个地址?

时间:2018-11-01 16:52:04

标签: assembly nasm x86-16

是否可以将同一字节快速移至一堆地址

pseudocode...
mov ax, 10
mov [memAddrStart to MemAddrEnd], ax

这会将AX放入每个地址中,因此我可以引用序列中的任何地址并始终获取10。

这有可能吗?如果没有,我该如何解决?

1 个答案:

答案 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)。