0

This code works in real mode. I have such example: This code goes to 0x001FFD50 address.

...
001F066F: push        es
001F0670: push        0FD50
001F0673: retf ^^^^^^
001F0674: push        00051
...

After that, I have such code:

I need to get back to the 0x001F0674 address.

...
001FFE91: push        00674
001FFE94: retn ^^^
...

But instead of that, I go to the 0x0674 address. How can I get back to the 0x001F0674 address in real mode?

Jester
  • 56,577
  • 4
  • 81
  • 125
user3360601
  • 327
  • 3
  • 17
  • 3
    You need to use `retf` to switch segments. Just use your first example, but `push 0x001F` instead of `es` obviously. Or, if `es` still contains `0x001F` then you can even keep that. – Jester Nov 25 '16 at 17:02
  • 3
    On second look, you seem to be in the same segment, so your code should actually work since you don't need to switch segment after all. – Jester Nov 25 '16 at 17:08
  • 1
    I assume everywhere you have something like `0x001FFD50` you really mean `0x001F:0xFD50` I ask because if that is the case those aren't 32-bit addresses, they are segment:offset (physical address = segment*16+offset) – Michael Petch Nov 25 '16 at 18:49
  • 2
    Well.. a trully physical address `0x001FFD50` in real mode does not exist, so it must be `001F:FD50` or the value is completely wrong. Then the physical address is `0x0FF40`. For `001F:0674` the physical address is `0x00864`. You can use `retn`, if you recalculate the offset based on your current `cs`, otherwise do `retf`. But if that code there is not PIC (Position-independent code), then it may expect particular `cs` value to be used (so code offsets will work). So it's not only about setting `cs:ip` to your desired address, but also to end with `cs` containing value which your code expect. – Ped7g Nov 25 '16 at 19:33
  • 1
    (about non-existent address ... I'm talking about pure 8086, I know on some later machines there may be few more bytes available beyond the basic 1MiB of address space) Check also http://stackoverflow.com/documentation/x86/3679/real-vs-protected-modes/12672/real-mode#t=201611251935033684519 – Ped7g Nov 25 '16 at 19:34
  • 2
    @Ped7g : Technically speaking it is possible to have code segments with 32-bit limits in real mode if you're on a 386 and you have put yourself into unreal mode - using cached descriptors (16-bit) with a 32-bit limit (2^32-1). This can be done for both code and data descriptors. Although from the question I highly doubt that he's using unreal mode with such a _CS_. Just mentioning the possibility. – Michael Petch Nov 25 '16 at 19:51

1 Answers1

0

Thank you for your suggestions!

You were right about segment and offset. But address 0x001F0674 was in file, and when I took dump from memory, I saw that segment there was different than 0x001F0674. It was 0x0018*16+0674.

Thanks a lot, @Jester, @Michael Petch, @Ped7g.

user3360601
  • 327
  • 3
  • 17