Most assembler offer many different methods to allocate memory. The following are a few methods to statically allocate memory for data.
.byte <byte-expr>{, <byte-expr>}*
<byte-expr> with
an expression that yields the value of a byte. You can
use commas to separate two or more bytes.
For example,
.byte 23, 42, 32
allocates enough space for three bytes, then initialize the bytes to the bit patterns for 23, 42 and 32.
.word <word-expr>{, <word-expr>}*
.byte, except each item is a 16-bit
pattern.
.int <int-expr>{, <int-expr>}*
.byte, except each item is an
``integer''. Unfortunately, the width of each integer is
platform dependent. It can be 16-bit or 32-bit.
.fill <repeat>[, <size>[, <value>]]
<repeat>
specifies the number of items to allocate and fill. Without
<size>, the default size is 1 byte. <size>
specifies the size of each repeating pattern. <value>
has a default of 0. However, you can specify it to be something
else.
The simplest use is as follows:
.fill 20
which allocates 20 bytes, and fill them all with the bit patterm of 0. The following does exactly the same thing:
.fill 20, 1, 0
.ascii <string>
The following is an example:
.ascii "Tak"
It allocates exactly 3 bytes for the ASCII codes of ``T'', ``a'' and ``k''.
.asciz <string>
The following is an example that allocates four bytes (one for the null terminator):
.asciz "Tak"
. = . + <int-expr>
.fill <int-expr>
to allocate the same space but keep it initialized to 0.
We can combine the use of the memory allocation directives mentioned above with the definition of labels. Observe the following example:
.data dogBiscuit: .fill 20, 1, 0xfd
It first switches to the data segment, then it defines a label,
dogBiscuit to be the ``current'' location of the segment.
After that, it allocates enough locations for
``20 1-byte values, each initialized to a value of 0xfd ''.
Effectively, dogBiscuit is defined to be the address of the
first byte of the 20 bytes allocated by the .fill directive.
With this directive, we can now use symbolic name instead of numbers to
refer to addresses. For example, the following code loads the address of
the first byte of dogBiscuit into register eax:
movl $dogBiscuit,%eax
You can also copy the word starting at the 4th byte at dogBiscuit
to register dx:
movw dogBiscuit+3, %dx
The +3 is not a typo. Because we count from 0, +3 really
means the fourth byte.
When you are debugging in gdb, you can view contents of memory using the x command. However, because gdb was originally designed to work with high-level languages, it does have some interesting behavior.
For example, if you type the following in gdb:
x dogBiscuit
It treats the four bytes starting at label dogBiscuit as an
address, and then attempts to display the contents that that address.
This is because in a high level programming language, there is no need
to look at bytes in memory uninterpreted. Programmers only need
to use the `x' command when they want to look at a chunk of memory
pointed to by a pointer. As a result, `x' treats any symbolic argument
as a pointer, and dereference it to display contents of memory.
If you want to display the content at dogBiscuit (i.e., not to
dereference the first four bytes of dogBiscuit), you need to
use the following instead:
x &dogBiscuit
If you want to specify the formatting of the output, you can use a
repeat count, followed by one format code. For example, if you want
to display the 20 bytes at dogBiscuit as 20 bytes, displayed
in binary, you can use the following command in gdb:
x/20t &dogBiscuit
Use ``help x'' in gdb to find out what else you can do with this useful command.
Copyright © 2009-04-16 by Tak Auyeung