News:

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

Main Menu

Printing with gdb in assembly

Started by johny23, April 20, 2016, 08:20:48 AM

Previous topic - Next topic

johny23

Say I have this variable in a program:


section. data
       numeric: DD 0x12345678


When I run gdb and prints it with p /x numeric, I get:
0x12345678

And when I print it with p /x (char[4]) numeric, I get it in little endian order:
{0x78, 0x56, 0x34, 0x12}.

What's the reason that I get it in different order in each one of the printings?

jj2007

The first one prints a full dword, the second one prints a sequence of four bytes.

johny23

But I still don't understand why I don't get this result in the first printing:

0x78563412

Ok, the command suppose to print a full dword- but from what I know, the number is represented at little endian in memory.
So, I expected the printing to be like I wrote above, and not like this:

0x12345678

Why it prints it in an order that is different from the order in memory?

hutch--

x86 stored data in a couple of different ways. Its called "little endian". When you print a complete DWORD the order is reversed and works the right way. When you print byte by byte you get it in memory order. Roughly memory order is how text is stored (left to right), numeric data is stored right to left as 4 bytes (for a DWORD).

johny23

When you say it works in the right way, do you mean only for cases when the data is kept in memory in a reversed order?

Because if for example I had this:


section .data
    string: DB 'abc'


p/x string  will give me:
0x636261

and p/x (char[4]) string will give me:
{0x61, 0x62, 0x63, 0x00}

hutch--

String data is stored in memory left to right, numeric data is stored right to left, its the format of little endian.

johny23

So when you said "right way" you meant that it prints the numeric from right to left?

mineiro

Each one of these letters that your're reading now are bytes if you do not consider unicode.
You write/read from left to right and up to down using english language, and this is the way that bytes (letters) are stored on hard disk or memory.
When you're doing math, like 9+1, the carry goes from right to left and result is 10. This is the way that you can consider while working with count. Can you see, 9 and 1 is only one 'letter' but when adding it they become two letters, to say, 10.
In other words, if you consider numbers as being text, so we go from left to righ, so 9+1 == 01, we throw the carry to the right ok. And we know that this is not valid, so we can reverse the result, so 01 reversed is 10, the answer that we expect.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

xanatose

The purpose of little endian is so that the pointer to a byte is the same as the pointer to a word, and the same as the pointer to a dword

.data
x dword 0

.code
mov edx, offset x
mov byte ptr [edx], 5

; x will be 5 on little endian
; On big endian x would be 05000000h

This is possible on little endian as the byte and the int points to the same memory area. On big endian the byte would be 3 bytes off thus making x 05000000h

In C you can do something like this

int x = 0;
*(char*)&x = 'Y';
printf("%s\n", (char*)&x);


On little endian you will get 'Y'. On big endian you will get an empty string.