News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Qword being inversed

Started by gelatine1, April 29, 2014, 06:03:18 AM

Previous topic - Next topic

gelatine1

Hi, I noticed today that the two dwords in a qword are read in a different direction. for example if I would have

integer64 dq 00001001000001110001101011010101  01100101100101000111001100101010b

Then my integer64 is being read as 01100101100101000111001100101010  00001001000001110001101011010101

Why does this happen ?
Maybe is it because lea eax,integer64 makes eax point to the last dword ? Or is this something because the hex codes are being read from right to left (for the arguments)?

raymond

(read my signature)
Quotedq 00001001000001110001101011010101  01100101100101000111001100101010b

First, I have to assume that the spaces left between the two 32-bit segments were not in your original script; otherwise, your assembler should have raised an exception with the spaces not being numerical characters.

Secondly, I have to assume that you have "printed out" the two dwords separately to get your reported result.

You must remember that numbers are kept in the "little endian" order in memory. If you had inspected the content of your memory where that qw was kept, you should have seen it stored as:
1010, 0010, 0011, 0111, 0100, 1001, 0101, 0110, 0101, 1101, 1010, 0001, 0111, 0000, 1001, 0000
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

MichaelW

As Raymond stated, what you are seeing is a result of the little-endian byte order used by x86 processors, where multi-byte values are stored in memory with the least significant byte at the lowest address, opposite of the order of the bytes in a register and the order in which we write numbers.

http://en.wikipedia.org/wiki/Endianness


include \masm32\include\masm32rt.inc

HEXDUMP MACRO address, paragraphs, zerobase
    invoke HexAsciiDump, address, paragraphs, zerobase
ENDM

.data
    _word   dw 0102h,0,0,0,0,0,0,0
    _dword  dd 01020304h,0,0,0
    _qword  dq 0102030405060708h,0
.code

;-----------------------------------------------------------------------
; This longer name avoids a conflict with the MASM32 HexDump procedure.
;-----------------------------------------------------------------------
HexAsciiDump proc startAddress:DWORD, nParagraphs:DWORD, fZeroBase:DWORD
    push ebx
    push edi
    push esi
    mov esi, startAddress
    xor ebx, ebx
    .WHILE ebx < nParagraphs
        mov eax, esi
        mov ecx, ebx
        shl ecx, 4
        .IF fZeroBase
            printf( "%08X  ", ecx )
        .ELSE
            add eax, ecx
            printf( "%08X  ", eax )
        .ENDIF
        xor edi, edi
        .WHILE edi < 16
            mov ecx, ebx
            shl ecx, 4
            add ecx, edi
            movzx eax, BYTE PTR [esi+ecx]
            printf( "%02X ", eax )
            .IF edi == 7
                printf( "- " )
            .ENDIF
            inc edi
        .ENDW
        printf( "  " )
        xor edi, edi
        .WHILE edi < 16
            mov ecx, ebx
            shl ecx, 4
            add ecx, edi
            movzx eax, BYTE PTR [esi+ecx]
            .IF eax > 31 && eax < 127
                printf( "%c", eax )
            .ELSE
                printf( "." )
            .ENDIF
            inc edi
        .ENDW
        printf( "\n" )
        inc ebx
    .ENDW
    pop esi
    pop edi
    pop ebx
    ret
HexAsciiDump endp

start:

    HEXDUMP OFFSET _word, 1, 0
    HEXDUMP OFFSET _dword, 1, 0
    HEXDUMP OFFSET _qword, 1, 0

    inkey
    exit

end start


00403000  02 01 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
00403010  04 03 02 01 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
00403020  08 07 06 05 04 03 02 01 - 00 00 00 00 00 00 00 00   ................




Well Microsoft, here's another nice mess you've gotten us into.

gelatine1

But why does it happen for qwords and not for dwords? I print each bit seperately by the way

K_F

I think you missed this
Quote
Code: [Select]
00403000  02 01 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
00403010  04 03 02 01 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
00403020  08 07 06 05 04 03 02 01 - 00 00 00 00 00 00 00 00   ................

'Sire, Sire!... the peasants are Revolting !!!'
'Yes, they are.. aren't they....'

gelatine1

If I use this instruction (esi points to the beginning of the Qword)

mov edx,[esi]

Then edx contains the first 32 bits in Big Endian (as I had stored them). is this due to characteristics of the mov instruction or am I still missing something ?

Edit:
I'm still wondering: If I would want to go through all of the bits of the 64bit integer, how would I do it ? (from lsb to msb, 2bytes at a time)
Would the following instruction fit ?
mov dx,[esi+2*ebx]
(if ebx increases from 0 to 3)

jj2007

The order is indeed a bit confusing. The best option to understand it is to use OllyDbg. Just run Olly, open the executable, press F8 and see how the registers change.

include \masm32\include\masm32rt.inc
.686p
.xmm

.code
src1   dq 01234567890abcdefh
   dq 0
src2   dq 0debc0a9067452301h
   dq 0

start:
   mov ebx, offset src1
   ; in Olly, select ebx, then right-click, follow in dump
   mov ecx, 0
   mov cl, [ebx]
   mov cx, [ebx]
   mov ecx, [ebx]
   movq xmm1, [ebx]

   mov esi, offset src2
   ; in Olly, select esi, then right-click, follow in dump
   mov eax, 0
   mov al, [esi]
   mov ax, [esi]
   mov eax, [esi]
   movq xmm0, [esi]

   exit

end start

dedndave

actually, i've gotten so used to it, it would seem awkward the other way around - lol
i remember "Little Endian" by intEL   :P

jj2007

Quote from: dedndave on April 30, 2014, 08:44:37 AM
actually, i've gotten so used to it, it would seem awkward the other way around

Yes, but it's only a habit and/or a convention. I guess it would be more consistent if we displayed everything from left to right, dumps and registers alike, i.e. if the least 2 bytes are 1234h, then al = 12, ax = 1234, eax=12340000

(I'm sure somebody will pop up and teach us why this would be 'against nature' 8))

MichaelW

The little-endian storage order is a design optimization that avoids having the operand address change with the operand size.
Well Microsoft, here's another nice mess you've gotten us into.

gelatine1

Thanks a lot guys, the answers really helped me a lot in understanding this :)