0

I am learning some gdb and it is covering examining arrays. There is the following code, and I see it is 4 bytes, and how a[1] = 2 in an array int a[] = {1,2,3}

(gdb) x/4xb a + 1
0x7fff5fbff570: 0x02  0x00  0x00  0x00

But what if a was greater than what could be shown by a single hex byte? Then how does it work for the second part? Sorry if this is unclear, I don't know how tow ord it exactly.

6
  • 1
    See Endianness
    – 0xec
    Aug 1 '14 at 5:25
  • I got that. Mine is little endian, or else it would go 0x00 0x00 0x00 0x02 But how do these four bytes come together into a single integer value?
    – user8058
    Aug 1 '14 at 5:34
  • 1
    0*256^3+0*256^2+0*256^1+2*256^0. If you have the hex bytes 0x12 0x34 0x56 0x78, this would be 0x12*256^3+0x34*256^2+0x56*256^1+0x78*256^0=305419896 (big endian) or 0x78*256^3+0x56*256^2+0x34*256^1+0x12*256^0=2018915346 (little endian). Aug 1 '14 at 6:47
  • 1
    Alternatively, you can specify the width of grouping by using x/?x. See here. Aug 1 '14 at 6:50
  • @GuntramBlohm That seems like a good answer, thank you.
    – user8058
    Aug 1 '14 at 16:59
2

I think you have two questions here. The first part is how to convert from decimal to hexadecimal and back; the second part is how a multi-byte value is represented in memory. Guntram Blohm's answer covers the first part in detail, and I'll try to muddle through an answer to the second here.

So, consider a multi-byte hexadecimal number...ABCD, where each letter represents a byte. So for example in 0x03B87C43 A represents 0x03, B represents 0xB8, C represents 7C and D represent 0x43. Finally, D is referred to as the low-order byte.

Now, the various bytes can be arranged in different ways in memory; and there are two major forms that are currently in use today:

little-endian form:

The low-order byte is placed at the lowest memory address, thus our example number would be stored in memory thusly:

 1000  1001  1002  1003   <----- memory addresses, notional     
+-----+-----+-----+-----+
|  D  |  C  |  B  |  A  |
+-----+-----+-----+-----+

Intel processors use this form of storing multi-byte numbers.

big-endian form:

The low-order byte is placed at the highest memory address, thus our example number would be stored in memory thusly:

 1000  1001  1002  1003   <----- memory addresses, notional     
+-----+-----+-----+-----+
|  A  |  B  |  C  |  D  |
+-----+-----+-----+-----+

Non-Intel SUN workstations use this form (IIRC they use a Motorola processor).

other forms.

just about any other arrangement can be used. For example, PDP-11 used a system where a 32-bit value was stored in little-endian format, with the exception of each byte of the 16-bit half was swapped. Thus our sample number would be stored in memory as:

 1000  1001  1002  1003   <----- memory addresses, notional     
+-----+-----+-----+-----+
|  C  |  D  |  A  |  B  |
+-----+-----+-----+-----+

Hope this helps a bit.

2

Too long for another comment ... You want to convert decimal to hex and vice versa?

Very short answer: Take windows calc, switch to programmer mode.

A bit longer answer: Get a calculator that can do hex, or a calculator app that can do it. I prefer realcalc on android.

Long answer:

To convert decimal to hex, divide your number by 16 and write down the remainder as a hex digit. Repeat with the divided number, prepending digits to the ones you've already written down. Continue until you reach zero. Group in 2 if you want bytes.

Example:

1_000_000 / 16 = 62_500, remainder 0 => 0
62_500 / 16 = 3_906, remainder 4 => 40
3_906 / 16 = 244. remainder 2 => 240
244 / 16 = 15, remainder 4 => 4240
15 / 16 = 0, remainder 15 => F4240, or 0F 42 40 in big endian, or 40 42 0F little endian.

To convert hex to decimal, take the left-most digit. Multiply by 16, add next digit. Repeat (multiply, add) until no more digits are left.

F4240 => 15
4240  => 15*16+4 = 244
240   => 244*16+2 = 3_906
40    => 3_906*16+4 = 62_450
0     => 62_450*16+0 = 1_000_000

If you want to do the same in bytes, not digits, it's the same, but with 256 as the multiplier. The values of the bytes 0x0f, 0x42, 0x40 are 15, 66 and 64.

F 42 40 => 15
42 40   => 15*256+66 = 3_906
40      => 3_906*256+64 = 1_000_000
3
  • When I'm in The Zone I don't need to mentally convert hex to dec... (Note: English thousands' separator is a comma, not a period.)
    – Jongware
    Aug 2 '14 at 18:13
  • @Jongware please note European thousands separator is a period not a comma. Aug 2 '14 at 20:35
  • 1
    Stop fighting :) I changed the separater to _, as you can in perl, to make it clear. Although i half expect someone to comment he wants to convert decimal numbers, not some strange numbering system he never heard of. Aug 3 '14 at 5:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.