Written by Harry Fairhead   
Friday, 15 January 2021
Article Index
Without Counting
Hex For Data

Hex for data

The reasons for using hex to represent addresses seem understandable but why use it for data?

The answer is that a single byte can store a number in the range 0 to 255 and this is often treated as a code for a displayable character. In this case the contents of a block of memory can be displayed as ASCII text which can be read, but if the memory is being used to store a program or some internally formatted data then displaying it as ASCII text produces nothing but a mess.

The solution is to display each byte as a hex value.

This is very neat because numbers in the range 0 to 255 correspond to 00 to FF in hex and so only two characters have to be allocated to each memory location in the display. (Compare this with the three needed if decimal is used!)

The other advantage of using hex is that particular data patterns are easier to spot in hex. For example you often get runs of FF, 0F or other simple hex values. Machine code instructions and even ASCII codes are also easier to spot in hex and if a item of data turns out to be an address what could be better than to have it already in hex!

Big-endian and little-endian

There is another useful feature of hex when used with addresses that allows the programmer to read a hex address when it is stored in a number of memory locations.

For example, suppose you want to store the data E3F7, as part of a program say, in two memory locations 1000 and 1001. You can do this without any need to resort to arithmetic by storing E3 in one location and F7 in other.

When the memory locations are put together then contents of the `high order byte' is placed in front of the contents of the low order byte to give the full address, E3F7. If the address had been written in decimal then things would be much more complicated.

For example, to store the address 1234 using two locations you have to split it up into a high and low byte:

high byte= INT(1234/256) = 4

low byte = 1234-INT(1234/256)*256 =210

which means that in decimal the high byte stores 4 and the low byte stores 210, which taken together look nothing like 1234.

It is much easier to work with hex because the splitting into high and low order bytes is just a matter of dividing up the hex digits two at a time.

This story would be complete and simple apart from the fact that the early computer chip makers, Intel, IBM, Motorola and Dec, couldn't agree on which order to store the bytes in.

In the case of Motorola and DEC the high order byte is always stored first. This is generally called Big-endian - decreasing numerical significance as the address increases or the big value first.  

This means that in a memory listing you can read hex addresses from right to left.

For example:

Address 00 01 02 03 04
        AF 34 FF 39 ...

can be read as two addresses, AF34 and FF39.

Unfortunately Intel and IBM store their addresses the other way around - that is, low order byte first. This is generally called Little-endian - increasing numerical significance as the address increases or little value first. 

This means that in a simple memory dump the pairs of hex digits that form the addresses are reversed. For example,

Address 00 01 02 03 04
        AF 34 FF 39 ...

in an Intel machine corresponds to the two addresses 34AF and 39FF.

If you swap between machines, especially any processor derived from the 68000 and the 80x86 family then you should watch out for this difference or risk getting your addresses in a twist. The same problem arises when transmitting bytes or bits even down a serial communication line - do you send the high byte or the low byte first. You always need to check which order the bits are in. The internet generally uses bigendian. 



Related Articles

Binary Arithmetic       

Assemblers and assembly language       

Reading A BMP File In JavaScript    

JavaScript Bit Manipulation  

C# Bit Bashing - The BitConverter             

The Mod function    

JavaScript Data Structures - Typed Arrays II             


What Programmers Know



  1. The Computer - What's The Big Idea?*
  2. The Memory Principle - Computer Memory and Pigeonholes*
  3. Principles of Execution - The CPU
  4. The Essence Of Programming
  5. Variables - Scope, Lifetime And More*
  6. Binary Arithmetic
  7. Hexadecimal*
  8. Binary - Negative Numbers*
  9. Floating Point Numbers*
  10. Inside the Computer - Addressing
  11. The Mod Function
  12. Recursion
  13. The Lost Art Of The Storage Mapping Function *
  14. Hashing - The Greatest Idea In Programming
  15. Advanced Hashing
  16. XOR - The Magic Swap*
  17. Programmer's Introduction to XML
  18. From Data To Objects*
  19. What Exactly Is A First Class Function - And Why You Should Care*
  20. Stacks And Trees*
  21. The LIFO Stack - A Gentle Guide*
  22. Data Structures - Trees
  23. Inside Random Numbers
  24. The Monte Carlo Method
  25. Cache Memory And The Caching Principle
  26. Data Compression The Dictionary Way
  27. Dates Are Difficult*
  28. Sequential Storage*
  29. Magic of Merging*
  30. Power of Operators
  31. The Heart Of A Compiler*
  32. The Fundamentals of Pointers
  33. Functional And Dysfunctional Programming*

* Recently revised

C book



or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.


Data Structures Part II - Stacks And Trees

Part II of our look at data takes us into more sophisticated structures that are fundamental to computing  - stacks, queues, deques and trees. If you don't know about these four then you are goin [ ... ]

XOR - The Magic Swap

We all know that if you want to swap the contents of two variables you need a third temporary variable to do the job. It's like swapping the contents of two mugs using a third to hold the contents of  [ ... ]

Other Articles







Last Updated ( Friday, 15 January 2021 )