Page 1 of 1

Copying data from memory to memory...

Posted: Wed Jul 04, 2007 8:06 am
by inflater
Hello,
I search for a answer for my question:

I am copying data from one address, e.g. 0xF000:0xFFF5, to [es:CopyPointer] (I don't know the exact value of CopyPointer's IP, so I am using this syntax). In FASM, I can't just

Code: Select all

mov si,[0xF000:0xFFF5]
I must assign the first hexadecimal number to some register, like CS, DS, ES, etc. So it looks like this:

Code: Select all

mov ax,0xF000
mov ds,ax
mov si,[ds:0xFFF5]
And I must copy data from 0xF000:0xFFF5 (length: 8 - one dword) to the mentioned address es:CopyPointer, using this code:

Code: Select all

push es
push ds
mov ax,ds           ;the pointer "CopyPointer" is located in the
mov es,ax           ;include files of my OS at the very *end* to prevent
mov ax,0xF000    ;memory overwriting - so let DS=ES
mov ds,ax
mov si,[ds:0xFFF5]
mov cx,8             ;length
mov di,CopyPointer ;MOVSB is always as DI taking the ES seg register
rep movsb           ;REP MOVSB instead of MOVSD, for safety I think
pop ds
pop es
but this wouldn't work at all, or, when ...

Code: Select all

mov  esi,CopyPointer
call   print_string
(you've guessed right, this is text data)

... this will display garbage or nothing at all.

NOTE: This code is in the first lines of my OS, so it's using real mode segmentation. After this and other things, it will jump into pmode.

Can you please tell me what the hell I'm doing wrong?

Regards inflater.

Posted: Wed Jul 04, 2007 8:25 am
by hailstorm
I have some kind of clue what you are doing wrong:
First of all, you mention you want to copy 8 bytes of data from the address 0xf000:0xfff5. (And yes, you have to set ds manualy)

But you are making a misstake while loading the si register. You get a certain offset from address 0xf000:fff5, instead of the address self.
Lets say that 0xf000:0xfff5 contains the word 0x3000, the complete address you get by loading si with [ds:0xfff5] is 0xf000:3000. That is where your data is copied from.

So the only thing you have to is to put 0xfff5 in si and you are done.

Posted: Wed Jul 04, 2007 8:33 am
by earlz
your code is very confusing at overwriting segment registers...I think it overwrote DS like 3 times for what I could see no real reason of...but anyway..

I really can't understand what your doing from the code, so I can't really try to fix it...

here is what I'd use (not tested though)

Code: Select all

;dunno what you'd need to save to the stack so...
;I see that I think CopyPointer's segment is DS, so I'll do that too

mov di,ds
mov es,di ;Set ES to DS
mov di,CopyPointer
;ES:DI now setup

mov si,0xF000
mov ds,si
mov si,0xFFF5
;DS:SI is now ready too

mov cx,8 ;length

rep movsb ;do it!

Posted: Wed Jul 04, 2007 8:40 am
by hailstorm
Good post!

But because of his pointer mambo-jambo, I really think he should figure this out himself. Just for his idea about addressing, you know? :wink:

Posted: Wed Jul 04, 2007 8:58 am
by inflater
@hckr: Hehe, you just changed AX to DI in the first and to SI in the second parts of the code :D It does the same effect if there was AX (like in my previous code). It still do modify the segment registers :) (So PUSH ES PUSH DS still are exist)
And the fix? I fixed it by MOVing SI to 0xFFF5, like hailstorm told me so and you had that in your code too ;)

Okay, the problem is fixed, thanks for your responses! :)

Regards,
inflater

Re: Copying data from memory to memory...

Posted: Wed Jul 04, 2007 9:28 am
by Brendan
Hi,
inflater wrote:In FASM, I can't just

Code: Select all

mov si,[0xF000:0xFFF5]
The CPU doesn't support that.... ;)

You could try something like:

Code: Select all

    push ds
    mov ax,0xF000
    mov ds,ax
    mov ax,[0xFFF5]
    mov bx,[0xFFF7]
    mov cx,[0xFFF9]
    mov dx,[0xFFFB]
    pop ds
    mov [CopyPointer],ax
    mov [CopyPointer+2],bx
    mov [CopyPointer+4],cx
    mov [CopyPointer+6],dx
If you know you're running on a 32-bit CPU, then you could do this (in real mode) instead:

Code: Select all

    mov ax,0xF000
    mov fs,ax
    mov eax,[fs:0xFFF5]
    mov ecx,[fs:0xFFF9]
    mov [CopyPointer],eax
    mov [CopyPointer+4],ecx
You could even try something like this (without a 32-bit CPU):

Code: Select all

    mov bx,sp
    mov cx,ss
    mov ax,0xF000
    cli
    mov ss,ax
    mov sp,0xFFF5
    pop word [CopyPointer]
    pop word [CopyPointer+2]
    pop word [CopyPointer+4]
    pop word [CopyPointer+6]
    mov ss,cx
    mov sp,bx
    sti
But your original code should've been:

Code: Select all

    push es
    push ds
    mov ax,ds           ;the pointer "CopyPointer" is located in the
    mov es,ax           ;include files of my OS at the very *end* to prevent
    mov ax,0xF000    ;memory overwriting - so let DS=ES
    mov ds,ax
    mov si,0xFFF5
    mov cx,4             ;length in words!
    mov di,CopyPointer ;MOVSW is always as DI taking the ES seg register
    cld
    rep movsw           ;REP MOVSW instead of MOVSD, for safety I think
    pop ds
    pop es
Or if you know it's a 32-bit CPU:

Code: Select all

    push es
    mov ax,ds
    mov es,ax
    mov ax,0xF000
    mov fs,ax
    mov si,0xFFF5
    mov di,CopyPointer
    cld
    fs movsd
    fs movsd
    pop es
Alternatively, if you're only printing it (and don't need to store it for later) you could try something like:

Code: Select all

    push ds
    mov ax,0xF000
    mov si,0xFFF5
    mov ds,ax
    cld
.next:
    lodsb
    mov ah,0x0E
    xor bx,bx
    int 0x10
    cmp si,0xFFFD
    jb .next
    pop ds
Yeah - I was bored.... ;)


Cheers,

Brendan

Posted: Wed Jul 04, 2007 9:55 am
by inflater
Brendan wrote:Yeah - I was bored....
OMG you really were bored :shock: 8-[ :mrgreen:

inflater

Posted: Wed Jul 04, 2007 10:44 am
by hailstorm
@Brendan: Show off! :mrgreen: