汇编中的内存复制 [英] in-memory copying in assembly

查看:29
本文介绍了汇编中的内存复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

First up, using NASM and the target is x86, and running in 16-bit Real Mode of x86. I want to copy code at one memory location to another, and then do a call/jmp to the destination, so I can execute the code there. The code is initially at 0x1000:0x0 (segment:offset). Now, I want to copy it to, say 0x3000:0x0. And the code is 512 bytes in size, exactly. I'm trying to do this with following routine.

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 吗?

The code being copied just prints a string. So if the above snippet works, I would see that string on screen. Also, I have verified that the copied code is working , and that it is indeed present at 0x1000:0x0, so no such obvious/silly mistakes made. The above routine is failing for some reason. The possible points of failure, in my opinion, could be wrong addresses given. I'm not sure of what to put in SI and DI before the copying. Should these be offsets or the actual address? The documentation doesn't make this clear. Also, should I be explicitly initializing ES and DS?

我尝试了各种不同的组合来尝试完成这项工作,但无济于事.其中之一是这样的:

I have tried various combinations of things to try to make this work, but to no avail. One of them was this:

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 字节,原始二进制).

So here I explicitly set ES:DI and DS:SI. This also did not work. I also tried giving the actual physical addresses to SI and DI, failed. Now, I'm out of options. I'm sure there's some conceptual memory addressing mistake being made here, but I'm not able to catch it. (And yeah, the code copied is 512 bytes in size, raw binary).

谢谢.

推荐答案

问题最终以一种奇怪的方式得到解决.好的,程序的前几行是这样的:

The problem got fixed in a weird way finally. Okay , the first few lines of the program had this:

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

接下来是复制程序.我将代码编辑为:(并且有效)

This was followed by the copying routine. I edited the code to this: (and it worked)

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

通过此更改,我发布的第一个复制例程也有效.我不知道为什么.我只是在玩弄这些段值,然后点击了.

With this change the first copy routine I posted, also worked. I don't know why though. I was just playing around with these segment values, and this clicked.

这篇关于汇编中的内存复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆