Magnus
Magnus

Reputation: 7821

Memory Locations of Variables when Using IA-32 Assembly Language

Quick question on memory locations in IA-32 assembly language that i cannot seem to find the answer for anywhere else.

On IA-32 each memory address is 4 bytes long (e.g. 0x0040120e). Each of these addresses points to a 1 byte value (or in the case of a larger value, the first byte of it). Now look at these two simple IA-32 assembly language statements:

var1 db 2
var2 db 3

This will place var1 and var2 in adjacent memory cells (let's say 0x0040120e and 0f). Now I realize that the define directive db allocates 1 byte to the value. But, in the case above I have two values (2 and 3) that in fact only requires two bits each, to be stored.

Questions:

  1. When using the db directive, do these two values still consume a full byte, even though they are smaller than 1 byte?
  2. Is using a full byte for values that could get away with less, still the common way to go (as we have so much memory that we don't care)?
  3. Does integers 0 to 255 then generally take up 1 byte and integers 256 to (2^16 - 1) take up 2 bytes (a word), etc.?

Thank you,

Magnus

EDIT 1: Made questions more clear (apologies for the back and forth)

EDIT 2: Added a structured reply below, based on other posters' input

Upvotes: 1

Views: 965

Answers (3)

Magnus
Magnus

Reputation: 7821

My initial question was a bit unstructured, so for the benefit of other searchers stopping by here I will use the answers received from @unwind and @geert3 to create a structured response. Again, this was my fault due to the initial poor structuring and creds for the answers goes to @unwind and @geert3.

  1. When using the db directive you allocate 1 byte to the variable, and even if the variable takes up less space than 1 byte, it will still consume that full 1-byte address spot. As one might guess, that wastes a few bits of memory, but that is okay as you have enough memory and not too bothered about wasting a couple of bits. The reason you want to use the full 1-byte memory location is that it is easier to reference the variable when it is alone in the address slot (see #geert3's note on how to access it if you use less than a byte), and additionally, in case you want to reuse the variable later, it is great to know you have space for any number up to 255.
  2. Yes, see answer to 1
  3. Yes, you would normally allocate multiples of a byte to a variable, in a byte-addressable system

Upvotes: 1

unwind
unwind

Reputation: 399833

Yes, since the architecture is byte-addressable and cannot address anything smaller than a byte.

This means that data requiring less than one byte will need to share its address with other data.

In practice this means that you're going to have to know which bits in the pointed-out byte are used for this particular value.

For hardware registers this sort of mapping is very common.

EDIT: Ah, you seem to mean "values of the same variable" when you said "2 and 3". I thought you meant 2-bit and 3-bit values. You need to decide how many bits are needed at most for a particular variable, for all the values you need that variable to be able to store. There are variable-length encodings for integers of course, but that's generally rarely used in assembly and not what you'd typically use for some general-purpose variable.

You generally should expect to reserve all bits required for all values that a variable need to hold, up front. Otherwise, if you're worried about "wasting memory", you would need to move all other variables as soon as you get some "vacant bits" somewhere. That would end up costing fantastically much. Also, knowing the size of a variable is constant makes it possible to generate (or write) the proper code to handle it, otherwise you would of course also need to explicitly store somewhere "the size of the value held in variable x is now y bits". That becomes extremely painful very very quickly.

Upvotes: 1

geert3
geert3

Reputation: 7321

yes. the B in DB is for Byte. You could use a nibble for each, like so:

combined db 0x23

but you'd have to a) shift the result for 4 bits right if you need the "2". b) mask the leftmost 4 bits if you need the "3". Hardly worth the effort these days ;-)

Upvotes: 2

Related Questions