首先,使用NASM,目标是x86,并在x86的16位实模式下运行。
我想将一个内存位置的代码复制到另一个内存位置,然后对目的地进行调用/跳转,这样我就可以在那里执行代码。代码最初位于 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 字节,原始二进制文件)。
Thanks.