简体   繁体   中英

in-memory copying in assembly

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.

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.

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).

Thanks.

Have you made sure that the code you copy is either position independent, or correct at address 0x3000 instead of 0x1000? Some instructions (like CALLs and long JMPs) are absolute, other (like short JMPs) are relative to the address of the instruction.

The second piece of example code you posted should work, as long as the direction flag is clear (do a "CLD" instruction if it might not be), and as long as you're not trashing your own stack or anything.

If it doesn't work (and given that the first example is so badly messed up), I'd be tempted to assume that you made a mistake somewhere else (eg maybe you loaded data from the wrong sector of the disk to 0x1000:0x0000, and you're correctly copying the wrong data or something).

Probably the best advice anyone can give you is to learn how to single-step through your code (and see register contents, set breakpoints, examine memory, etc) with something like the debugger built into the Bochs emulator.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM