Assembly Language for Beginners

(nextflipdebug2) #1

2.9 Memory.


(((char)&v)+3));
};


After running it we get:


root@debian-mips:~# ./a.out
00 00 00 7B


That is it. 0x7B is 123 in decimal. In little-endian architectures, 7B is the first byte (you can check on x86
or x86-64), but here it is the last one, because the highest byte goes first.


That’swhythereareseparateLinuxdistributionsforMIPS(“mips”(big-endian)and“mipsel”(little-endian)).
It is impossible for a binary compiled for one endianness to work on anOSwith different endianness.


There is another example of MIPS big-endiannes in this book:1.24.4 on page 365.


2.8.4 Bi-endian.


CPUs that may switch between endianness are ARM, PowerPC, SPARC, MIPS,IA64^24 , etc.


2.8.5 Converting data


TheBSWAPinstruction can be used for conversion.


TCP/IP network data packets use the big-endian conventions, so that is why a program working on a little-
endian architecture has to convert the values. Thehtonl()andhtons()functions are usually used.


In TCP/IP, big-endian is also called “network byte order”, while byte order on the computer “host byte
order”. “host byte order” is little-endian on Intel x86 and other little-endian architectures, but it is big-
endian on IBM POWER, sohtonl()andhtons()don’t shuffle any bytes on the latter.


2.9 Memory


There are 3 main types of memory:



  • Global memoryAKA“static memory allocation”. No need to allocate explicitly, the allocation is
    performed just by declaring variables/arrays globally. These are global variables, residing in the
    data or constant segments. They are available globally (hence, considered as ananti-pattern). Not
    convenient for buffers/arrays, because they must have a fixed size. Buffer overflows that occur here
    usually overwrite variables or buffers residing next to them in memory. There’s an example in this
    book:1.9.3 on page 76.

  • StackAKA“allocate on stack”. The allocation is performed just by declaring variables/arrays locally
    in the function. These are usually local variables for the function. Sometimes these local variable
    are also available to descending functions (tocalleefunctions, if caller passes a pointer to a variable
    to thecalleeto be executed). Allocation and deallocation are very fast, it justSPneeds to be shifted.


But they’re also not convenient for buffers/arrays, because the buffer size has to be fixed, unless
alloca()(1.7.2 on page 35) (or a variable-length array) is used. Buffer overflows usually overwrite
important stack structures:1.20.2 on page 275.


  • HeapAKA“dynamic memory allocation”. Allocation/deallocation is performed by calling
    malloc()/free()ornew/deletein C++. This is the most convenient method: the block size may
    be set at runtime.


Resizing is possible (usingrealloc()), but can be slow. This is the slowest way to allocate memory:
thememoryallocatormustsupportandupdateallcontrolstructureswhileallocatinganddeallocating.
Buffer overflows usually overwrite these structures. Heap allocations are also source of memory leak
problems: each memory block has to be deallocated explicitly, but one may forget about it, or do it
incorrectly.

(^24) Intel Architecture 64 (Itanium)

Free download pdf