Chapter7 Structure & C++
Online Structure Assembly and C++
1. Structures Introduction Memory alignment Bit Fields Using structure in Assembly
Introduction of structure Structures are used in C to group together related data into a composite variable. This technique has several advantages: It clarifies the code by showing that the data defined in the structure are intimately related. It simplifies passing the data to functions. Instead of passing multiple variables separately, they can be passed as a single unit. It increases the locality of the code.
See structure from the assembly standpoint a structure can be considered as an array with elements of varying size. A structure’s elements do not have to be the same size. Because of this each element of a structure must be explicitly specified and is given a tag instead of a numerical index. To access an element, one must know the starting address of the structure and the relative offset of that element from the beginning of the structure.
An example of a structure The elements of a structure are arranged in the memory in the same order as they are defined in the struct definition. It also states that the first element is at the very beginning of the structure. The macro offsetof() computes and returns the offset of any element of a structure. It takes two parameters, the first is the name of the type of the structure, the second is the name of the element to find the offset of. Thus, the result of offsetof(S, y) would be 2
Memory alignment Using gcc, the compiler inserts two unused bytes into the structure to align y (and z) on a double word boundary. Different C compilers may give different offsets to the elements.
Bit Fields Bit fields allow one to specify members of a struct that only use a specified number of bits. The size of bits does not have to be a multiple of eight. A bit field member is defined like an unsigned int or int member with a colon and bit size appended to it.
An example of bitfield The first bitfield is assigned to the least significant bits of its double word
A direct read command for a SCSI device #define MS OR BORLAND (defined( BORLANDC ) || defined( MSC VER)) #if MS OR BORLAND # pragma pack(push) # pragma pack(1) #endif struct SCSI read cmd { unsigned opcode : 8; unsigned lba msb : 5; unsigned logical unit : 3; unsigned lba mid : 8; / middle bits / unsigned lba lsb : 8; unsigned transfer length : 8; unsigned control : 8; } #if defined( __GNUC__ ) __attribute__ ((packed)) ; # pragma pack(pop)
Another defintion that works for all three compilers. If the sizeof(SCSI read cmd) expression is evalutated, Microsoft C will return 8, not 6! The reader should not be discouraged if he found the previous discussion confusing. It is confusing! The author often finds it less confusing to avoid bit fields all together and use bit operations to examine and modify the bits manually.
Using structure in Assembly When passed by value, the entire data in the structure must be copied to the stack and then retrieved by the routine. It is much more efficient to pass a pointer to a structure instead.
2. Assembly and C++ Overloading and Name Mangling References Inline functions Classes Inheritance and Polymorphis Other C++ features The C++ programming language is an extension of the C language. Many of the basic rules of interfacing C and assembly language also apply to C++. However, some rules need to be modified. Also, some of the extensions of C++ are easier to understand with a knowledge of assembly language. This section assumes a basic knowledge of C++.
Overloading and Name Mangling #include <stdio.h> void f ( int x ){ printf (”%d\n”, x); } void f ( double x ){ printf (”%g\n”, x);} Overloading and Name Mangling When more than one function share the same name, the functions are said to be overloaded. name mangling or modifying the symbol used to label the function. The mangled name encodes the signature of the function. The signature of a function is defined by the order and the type of its parameters. void f ( int x , int y , double z); DJGPP would mangle its name to be _f_Fiid and Borland to @f$qiid.
Extern keyword C++ allow it to specify that the function or global variable it modifies uses the normal C conventions. extern ”C” int printf ( const char , ... ); extern ”C”{ /* C linkage global variables and function prototypes / } #ifdef cplusplus #endi
References References are another new feature of C++. They allow one to pass parameters to functions without explicitly using pointers. void f ( int & x ) { x++; } int main() { int y = 5; f(y); // reference to y is passed , note no & here! printf (”%d\n”, y); // prints out 6! return 0; } C++ that allows one to define meanings for common operators on structure or class types. operator +(&a,&b) operator +(a,b) &a + &b a+b
Inline functions inline int inline_f ( int x ) { return x*x; } int f ( int x ) int main() { int y , x = 5; y = f(x); y = inline_f (x); return 0; }
Two advantages and the main disadvantage to inlining The inline function is faster. No parameters are pushed on the stack, no stack frame is created and then destroyed, no branch is made. Secondly, the inline function call uses less code! The main disadvantage of inlining is that inline code is not linked and so the code of an inline function must be available to all files that use it.
Classes A C++ class describes a type of object. An object has both data members and function members. The functions are not stored in memory assigned to the structure. Member functions are different from other functions. They are passed a hidden parameter. This parameter is a pointer to the object that the member function is acting on.
A simple C++ class void set data ( Simple object , int x ) { object−>data = x; } C Version of Simple::set data()
The example: Big_int class big_int.hpp big_math.asm test_big_int.cpp
Simple inheritance Inheritance allows one class to inherit the data and methods of another.
Assembly Code for Simple Inheritance
Plymorphic inheritance
Assembly Code for f() Function
Other C++ features The workings of other C++ features (e.g., RunTime Type Information, exception handling and multiple inheritance) are beyond the scope of this text. If the reader wishes to go further, a good starting point is The Annotated C++ Reference Manual by Ellis and Stroustrup and The Design and Evolution of C++ by Stroustrup.
End