汇编中的内存中复制

时间:2011-11-24 14:03:52

标签: assembly x86

首先,使用NASM,目标是x86,并在x86的16位实模式下运行。 我想将一个内存位置的代码复制到另一个内存位置,然后对目标执行调用/ jmp,这样我就可以在那里执行代码了。代码最初位于0x1000:0x0(段:偏移量)。现在,我想复制它,比如说0x3000:0x0。而且代码大小完全是512字节。我正试图通过以下例程来做到这一点。

org 0x500

;The code to be copied is located at 0x1000:0x0. We want to copy it to 0x3000:0x0

copy:

  mov esi,0x1000  ; source address of the code in DS:SI
  mov edi,0x3000  ; destination address of the code in ES:DI
  mov ecx,0x200   ; size of the code, 512 bytes (0x200)
  rep movsb       ; copy bytes from address in SI to address in DI.

  jmp 0x3000:0x0  ; jump to the destination , and execute the code there.

正在复制的代码只打印一个字符串。因此,如果上面的代码段工作,我会在屏幕上看到该字符串。此外,我已经验证复制的代码是有效的,并且确实存在于0x1000:0x0,所以没有出现这样明显/愚蠢的错误。 由于某种原因,上述例程失败了。在我看来,可能的失败点可能是错误的地址。在复制之前,我不确定在SI和DI中放入什么。这些应该是抵消还是实际地址?文档没有说清楚。另外,我应该明确初始化ES和DS吗?

我尝试了各种各样的组合来尝试使这项工作,但无济于事。其中一个就是:

org 0x500

;The code to be copied is located at 0x1000:0x0. We want to copy it to 0x3000:0x0

copy:
  mov bx,0x1000
  mov ds,bx       ; set DS explicitly to 0x1000.
  mov esi,0x0     ; source address of the code in DS:SI (0x1000:0x0)
  mov bx,0x3000
  mov es,bx       ; set ES explicitly to 0x3000
  mov edi,0x0     ; destination address of the code in ES:DI (0x3000:0x0)
  mov ecx,0x200   ; size of the code, 512 bytes (0x200)
  rep movsb       ; copy bytes from address in SI to address in DI.

  jmp 0x3000:0x0  ; jump to the destination , and execute the code there.

所以在这里我明确设置了ES:DI和DS:SI。这也行不通。我也试过给SI和DI提供实际的物理地址,但是失败了。现在,我没有选择。我确信在这里有一些概念性的内存寻址错误,但是我无法理解它。 (是的,复制的代码大小为512字节,原始二进制)。

感谢。

3 个答案:

答案 0 :(得分:2)

您确定要复制的代码是位置无关的,还是在地址0x3000而不是0x1000处正确?一些指令(如CALL和长JMP)是绝对的,其他指令(如短JMP)是相对于指令的地址。

答案 1 :(得分:0)

你发布的第二段示例代码应该可以工作,只要方向标志是明确的(如果它可能不是那么做一个“CLD”指令),并且只要你没有丢弃你自己的堆栈或任何东西

如果它不起作用(并且鉴于第一个例子非常混乱),我很想假设你在其他地方犯了一个错误(例如,你可能从磁盘的错误扇区加载了数据)到0x1000:0x0000,你正确地复制了错误的数据或其他东西。)

任何人都可以给你的最佳建议可能是学习如何单步执行代码(并查看注册内容,设置断点,检查内存等),例如Bochs模拟器中内置的调试器。

答案 2 :(得分:-2)

最终以一种奇怪的方式解决了这个问题。好的,该计划的前几行有这个:

org 0x500
mov ax,cs
mov ds,ax
mov es,ax

接下来是复制程序。我编写了代码:(并且有效)

org 0x500  
xor ax,ax  ;make ax 0, instead of copying CS to it
mov ds,ax
mov es,ax

通过此更改,我发布的第一个复制例程也有效。我不知道为什么。我正在玩这些段值,然后单击。