Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS 201 Structures Pointers. – 2 – Structures A structure is a complex data type Defined by the programmer Keeps together pertinent information of an object.

Similar presentations


Presentation on theme: "CS 201 Structures Pointers. – 2 – Structures A structure is a complex data type Defined by the programmer Keeps together pertinent information of an object."— Presentation transcript:

1 CS 201 Structures Pointers

2 – 2 – Structures A structure is a complex data type Defined by the programmer Keeps together pertinent information of an object Contains simple data types or other complex data types Similar to a class in C++ or Java, but without methods

3 – 3 – Structures Example from graphics: a point has two coordinates struct point { double x; double y; }; x and y are called members of struct point. Since a structure is a data type, you can declare variables: struct point p1, p2; What is the size of struct point? 16

4 – 4 – Accessing structures struct point { double x; double y; }; struct point p1; Use the “. ” operator on structure objects to obtain members p1.x = 10; p1.y = 20; Use the “ -> ” operator on structure pointers to obtain members struct point *pp=&p1; double d; Long-form for accessing structures via pointer d = (*pp).x; Short-form using “ -> ” operator d = pp->x; Initializing structures like other variables: struct point p1 = {320, 200}; Equivalent to: p1.x = 320; p1.y = 200;

5 – 5 – More structures Structures can contain other structures as members: struct rectangle { struct point pt1; struct point pt2; }; What is the size of a struct rectangle? Structures can be arguments of functions Passed by value like most other data types Compare to arrays int ptinrect(struct point p, struct rectangle r) { return p.x >= r.pt1.x && p.x < r.pt2.x && p.y >= r.pt1.y && p.y < r.pt2.y; } What does this function return? 32 0x1 when point p is in rectangle r, otherwise 0x0

6 – 6 – Operations on structures Legal operations Copy a structure (assignment equivalent to memcpy) Get its address Access its members Illegal operations Compare content of structures in their entirety Must compare individual parts Structure operator precedences “. ” and “ -> ” higher than other operators *p.x is the same as *(p.x) ++p->x is the same as ++(p->x)

7 – 7 – C typedef C allows us to declare new datatypes using “ typedef” keyword The thing being named is then a data type, rather than a variable typedef int Length; Length sideA;// may be more intuitive than int sideA; Often used when working with structs typedef struct tnode { char *word; int count; Treeptr left; Treeptr right; } Treenode; Treenode td;// struct tnode td;

8 – 8 – Self-referential structures A structure can contain members that are pointers to the same struct (i.e. nodes in linked lists) struct tnode { char *word; int count; struct tnode *next; } p;

9 – 9 – Self-referential structures Declared via typedef structs and pointers What does this code do? typedef struct tnode *nptr; typedef struct tnode { char *word; int count; nptr next; } Node; static nptr Head = NULL; // The head of a list … nptr np; // temporary variable while (… something …){ // Allocate a new node np = (nptr) malloc(sizeof(Node)); // Do some kind of processing np->word = … something …; np->next = Head; Head = np; }

10 – 10 – struct rec { int i; int a[3]; int *p; }; Assembly # %eax = val # %edx = r movl %eax,(%edx)# Mem[r] = val void set_i(struct rec *r, int val) { r->i = val;} Structures in assembly Concept Contiguously-allocated region of memory Members may be of different types Accessed statically, code generated at compile-time Accessing Structure Member Memory Layout iap

11 – 11 – struct rec { int i; int a[3]; int *p; }; # %ecx = idx # %edx = r leal 0(,%ecx,4),%eax# 4*idx leal 4(%eax,%edx),%eax# r+4*idx+4 int * find_a (struct rec *r, int idx) { return &r->a[idx]; } Example iap 0416 r *idx r

12 – 12 – Practice problem 3.39 What are the offsets (in bytes) of the following fields? p s.x s.y next How many total bytes does the structure require? Consider the following C code: Fill in the missing expressions struct prob { int *p; struct { int x; int y; } s; struct prob *next; }; movl 8(%ebp),%eax movl 8(%eax),%edx movl %edx,4(%eax) leal 4(%eax),%edx movl %edx,(%eax) movl %eax,12(%eax) void sp_init(struct prob *sp) { sp->s.x = ___________; sp->p = ___________; sp->next = ___________; }

13 – 13 – Practice problem 3.39 What are the offsets (in bytes) of the following fields? p0 s.x4 s.y8 next12 How many total bytes does the structure require?16 Consider the following C code: Fill in the missing expressions struct prob { int *p; struct { int x; int y; } s; struct prob *next; }; movl 8(%ebp),%eax movl 8(%eax),%edx movl %edx,4(%eax) leal 4(%eax),%edx movl %edx,(%eax) movl %eax,12(%eax) void sp_init(struct prob *sp) { sp->s.x = sp->s.y; sp->p = &(sp->s.x); sp->next = sp; }

14 – 14 – Aligning structures Structures and their members must be aligned at specific offsets in memory Goal: Align data so that it does not cross access boundaries and cache line boundaries Why? Low-level memory access done in fixed sizes at fixed offsets Alignment allows items to be retrieved with one access Storing an integer at 0x00 »Single memory access to retrieve value Storing an integer at 0x02 »Two memory accesses to retrieve value i386: 4-byte accesses at addresses that are multiples of 4 Addressing code simplified Scaled index addressing mode works better with aligned members

15 – 15 – Alignment of structure members Mostly matches the size of the data type char is 1 byte Can be aligned arbitrarily short is 2 bytes Member must be aligned on even addresses (i.e. starting address of short must be divisible by 2) int, float, and pointers are 4 bytes Member must be aligned to addresses divisible by 4 double is 8 bytes Special case

16 – 16 – Alignment of double precision gcc decided not to optimize for floating point If you want doubles in structures and you are going to access them, then make sure they are aligned yourself or pay the performance penalty Thus, alignment requirement for double is… 8 for Windows 4 for Linux

17 – 17 – struct S1 { char c; int i[2]; double v; } *p; Alignment with Structures Each member must satisfy its own alignment requirement Overall structure must also satisfy an alignment requirement “K” K = Largest alignment of any element Initial address must be multiple of K Structure length must be multiple of K For arrays of structuresExample What is K for S1 on Windows? What is the size of S1? Draw S1 and the alignment of elements within it ci[0]i[1]v p+0p+4p+8p+16p+24 Multiple of 4 Multiple of 8 K = 8, due to double element (for Windows)

18 – 18 – Linux vs. Windows Windows (including Cygwin): K = 8, due to double elementLinux: K = 4; double treated like a 4-byte data type struct S1 { char c; int i[2]; double v; } *p; ci[0]i[1] p+0p+4p+8 Multiple of 4 v p+12p+20 Multiple of 4 ci[0]i[1]v p+0p+4p+8p+16p+24 Multiple of 4 Multiple of 8 K = 8, due to double element (for Windows)

19 – 19 – Examples struct S2 { double x; int i[2]; char c; } *p; struct S3 { float x[2]; int i[2]; char c; } *p; p+0p+12p+8p+16 Windows : p+24 Linux : p+20 ci[0]i[1]xci[0]i[1] p+0p+12p+8p+16p+20 x[0]x[1] p+4 Draw the allocation for this structure What is K for Windows? for Linux? p must be multiple of 4 (in either OS) 8 for Windows 4 for Linux Draw the allocation for this structure What is K?

20 – 20 – Reordering to reduce wasted space struct S4 { char c1; double v; char c2; int i; } *p; struct S5 { double v; char c1; char c2; int i; } *p; c1iv p+0p+20p+8p+16p+24 c2c1iv p+0p+12p+8p+16 c2 10 bytes wasted space in Windows 2 bytes wasted space

21 – 21 – Practice problem 3.41 For each of the following structure declarations, determine the offset of each field, the total size of the structure, and its alignment requirement under Linux IA32 struct P1 {int i; char c; int j; char d;}; struct P2 {int i; char c; char d; int j;}; struct P3 {short w[3]; char c[3];}; struct P4 {short w[3]; char *c[3];}; struct P5 {struct P1 a[2]; struct P2 *p} 0, 4, 8, 12 : 16 bytes : 4 0, 4, 5, 8 : 12 bytes : 4 0, 6 : 10 bytes : 2 0, 8 : 20 bytes : 4 0, 32 : 36 bytes : 4

22 – 22 – Arrays of Structures Principle Allocated by repeating allocation for array type a[0] a+0 a[1]a[2] a+12a+24a+36 a+12a+20a+16a+24 struct S6 { short i; float v; short j; } a[10]; a[1].ia[1].ja[1].v

23 – 23 – Satisfying Alignment within Arrays Achieving Alignment Starting address must be K aligned a must be multiple of 4 Individual array elements must be K aligned Structure padded with unused space to be 12 bytes (multiple of 4) As a result, size of structure is a multiple of K Structure members must meet their own alignment requirement v ’s offset of 4 is a multiple of 4 struct S6 { short i; float v; short j; } a[10]; a[0] a+0 a[i] a+12i a+12ia+12i+4 a[1].ia[1].ja[1].v Multiple of 4

24 – 24 – Practice problem What is the size of this structure? Write assembly instructions to load a.c[1] into %eax Start with movl $a, %ebx struct P4 { short w[3]; char *c[3]; short j; } a; movl 12(%ebx),%eax 24 bytes (w=8, c=12, j=4)

25 – 25 – Exercise struct point { double x; double y }; struct octagon { // An array can be an element of a structure... struct point points[8]; } A[34]; struct octagon *r = A; r += 8; What is the size of a struct octagon? What is the difference between the address r and the address A? 16*8 = *8 = 1024

26 – 26 – Unions A union is a variable that may hold objects of different types and sizes Sort of like a structure with all the members on top of each other. The size of the union is the maximum of the size of the individual datatypes Examples: Combining low and high timestamps union U1 { char c; int i[2]; double v; } *up; c i[0]i[1] v up+0up+4up+8

27 – 27 – Unions union u_tag { int ival; float fval; char *sval; } u; u.ival = 14; u.fval = 31.3; u.sval = (char *) malloc(strlen(string)+1); What’s the size of u? What exactly does u contain after these three lines of code?

28 – 28 – typedef union { float f; unsigned u; } bit_float_t; float bit2float(unsigned u) { bit_float_t arg; arg.u = u; return arg.f; } u f 04 unsigned float2bit(float f) { bit_float_t arg; arg.f = f; return arg.u; } Using Union to Access Bit Patterns Get direct access to bit representation of float bit2float generates float with given bit pattern NOT the same as (float) u float2bit generates bit pattern from float NOT the same as (unsigned) f

29 – 29 – Bit Fields If you have multiple Boolean variables, you may save space by just making them bit fields Used heavily in device drivers Simplifies code The Linux system call to open a file: int fd = open(“file”, O_CREAT|O_WRONLY|O_TRUNC); Second argument is an integer, using bit fields to specify how to open it. In this case, create a new file if it doesn’t exist, for writing only, and truncate the file if it already exists.

30 – 30 – Implementing Bit Fields You can use an integer and create bit fields using bitwise operators: 32 bit-field flags in a single integer Via #defines #define A 0x01 #define B 0x02 #define C 0x04 #define D 0x08 Note that they are powers of two corresponding to bit positions Via enum Constant declarations (i.e. like #define, but values are generated if not specified by programmer) enum { A = 01, B = 02, C = 04, D = 08 };Example int flags; flags |= A | B;

31 – 31 – Bit field implementation via structs Use bit width specification in combination with struct Give names to 1-bit members struct { unsigned int is_keyword : 1; unsigned int is_extern : 1 ; unsigned int is_static : 1; }; Data structure with three members, each one bit wide What is the size of the struct? 4 bytes

32 CS 201 Advanced pointers

33 – 33 – Pointers Central to C (but not other languages) Gives uniform access to data structures (via physical address) Often a source of confusion to novice programmers Major concepts so far Every pointer has a type Every pointer has a value (an address) Pointers created via the “&” operator Dereferenced with the “*” operator Arrays and pointers closely relatedNow Pointers can also point to functions

34 – 34 – Function pointers Pointers until now point to data locations Pointers can also point to code locations Function pointers Store and pass references to code Have a type associated with them The type the function returns Some uses Dynamic “late-binding” of functions Dynamically “set” a random number generator Replace large switch statements for implementing dynamic event handlers »Example: dynamically setting behavior of GUI buttons Emulating “virtual functions” and polymorphism from OOP qsort() with user-supplied callback function for comparison »man qsort Operating on lists of elements »multiplication, addition, min/max, etc.

35 – 35 – Function pointers Example declaration int (*func)(char *); func is a pointer to a function taking a char * argument, returning an int How is this different from int *func(char *) ? Using a pointer to a function: int foo(char *); // foo: function returning an int int foo(char *); // foo: function returning an int int (*bar)(char *); // bar: pointer to a fn returning an int int (*bar)(char *); // bar: pointer to a fn returning an int bar = foo; // Now the pointer is initialized bar = foo; // Now the pointer is initialized x = bar(p); // Call the function x = bar(p); // Call the function

36 – 36 – Function pointers example #include void print_even(int i){ printf("Even %d\n“,i);} void print_odd(int i) { printf("Odd %d\n”,i); } int main(int argc, char **argv) { void (*fp)(int); int i = argc; if (argc%2) fp=print_even; else fp=print_odd; fp(i); } mashimaro %./funcp a Even 2 mashimaro %./funcp a b Odd 3 mashimaro % main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $4, %esp movl (%ecx), %eax movl $print_even, %edx testb $1, %al jne.L4 movl $print_odd, %edx.L4: movl %eax, (%esp) call *%edx addl $4, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret

37 – 37 – typedefs with function pointers Same as with other data types int (*func)(char *); The named thing – func – is a pointer to a function returning int typedef int (*func)(char *); The named thing – func – is a data type: pointer to function returning int

38 – 38 – Using pointers to functions // function prototypes int doEcho(char*); int doExit(char*); int doHelp(char*); int setPrompt(char*); // dispatch table section typedef int (*func)(char*); typedef struct{ char* name; func function; } func_t; func_t func_table[] = { { "echo", doEcho }, { "exit", doExit }, { "quit", doExit }, { "help", doHelp }, { "prompt", setPrompt }, }; #define cntFuncs (sizeof(func_table) / sizeof(func_table[0])) // find the function and dispatch it for (i = 0; i < cntFuncs; i++) { if (strcmp(command,func_table[i].name)==0){ done = func_table[i].function(argument); break; } if (i == cntFuncs) printf("invalid command\n") ;

39 – 39 – Complicated declarations C’s use of () and * makes declarations involving pointers and functions extremely difficult Helpful rules “*” has lower precedence than “()” Work from the inside-out Consult K&R Chapter 5.12 for complicated declarations dc1 program to parse a declaration

40 – 40 – C pointer declarations int *p int *p[13] int *(p[13]) int **p int *f() int (*f)() p is a pointer to int p is an array[13] of pointer to int p is a pointer to a pointer to an int f is a function returning a pointer to int f is a pointer to a function returning int

41 – 41 – Practice What kind of things are these? int *func(char*); int (*func)(char*); int (*daytab)[13]; int *daytab[13]; fn that takes char* as arg and returns an int* pointer to a fn taking char* as arg and returns an int pointer to an array[13] of ints array[13] of int*

42 – 42 – C pointer declarations Read from the “inside” out. int (*(*f())[13])() int (*(*x[3])())[5] char (*(*x())[])(); f is a function returning ptr to an array[13] of pointers to functions returning int x is an array[3] of pointers to functions returning pointers to array[5] of ints x is a function returning a pointer to an array of pointers to functions returning char

43 – 43 – Extra slides

44 – 44 – struct rec { int i; int a[3]; int *p; }; # %edx = r movl (%edx),%ecx# r->i leal 0(,%ecx,4),%eax# 4*(r->i) leal 4(%edx,%eax),%eax# r+4+4*(r->i) movl %eax,16(%edx)# Update r->p void set_p(struct rec *r) { r->p = &r->a[r->i]; } Example C Code ia 0416 Element i iap 0416

45 – 45 – What is the size of this structure? struct node{ char c; int i; }; The ‘sizeof’ operator tells us the size of a structure: n = sizeof(struct node); Why is the size not necesarily the sum of the sizes of its members? What is the offset of c within the structure? What is the offset of i within the structure? Rule of thumb: Elements stored in order at alignments that match their types. Exception: Linux double (4-byte aligned)

46 – 46 – Structures can be nameless A variable called koy, whose type is this structure, which has no name: Can not declare other variables of same type Can not pass in function parameters struct { char *key; int v[22]; } koy; A data type called key, which is this structure, which otherwise has no name Can use type ‘key’ to declare additional variables Can use type ‘key’ in function parameters typedef struct { char *key; int v[22]; } key;

47 – 47 – Structures can be assigned struct key { char *key; int v[22]; }; typedef struct key key; main() { key key, koy; int i; key.key = "key"; for(i=0; i<22; i++) key.v[i] = i; koy = key; // structure assignment printf("koy.key = %s, koy.v[11] = %d\n", koy.key, koy.v[11]); } see examples/struct.assign.c Note: arrays can not be assigned, but as part of a structure they can.

48 – 48 – Exercise struct key { char *word; int count; }; Declare an array of “ struct key ” whose name is keytab. Initialize the array keytab to contain the following values: {“auto”, 0} {“break”, 0} {“case”, 0} {“char”, 0} Then declare a pointer to keytab and using that pointer, write an expression whose value is the string “ case ”

49 – 49 – Practice Problem Imagine an application that passes binary messages between computers in two separate departments of a large organization. When the application is tested, it is discovered that through some terrible misjudgment, one department has purchased hundreds of Sun workstations while the other has hundreds of PC’s. A function is required to convert big-endian integers to little-endian and vice versa. Write the function int reverse_ends(int) using a union.

50 – 50 – struct node{ int i; char c; }; What is the offset of c within the structure? What is the offset of i within the structure? What is the size of this structure?

51 – 51 – Take a look at the function addtree in K&R, page 141 You can build a list of words in alphabetical order without ever moving data around. Only manipulating pointers to structures. Function treeprint from K&R, p. 142: void treeprint(struct tnode *p) { if (p != NULL { treeprint(p->left); printf( « %4d %s\n », p->count, p->word); treeprint(p->right); }

52 – 52 – struct rectangle * ptinrect(struct point p, struct rectangle *r, int n) { int i; for(i = 0; i < n; i++) { if(p.x >= r->pt1.x && p.x pt2.x && p.y >= r->pt1.y && p.y pt2.y) return r; r++; } return ((struct rectangle *)0); } Arrays of structures Pointers/arrays for structures just like other data types Can use Rarray[idx] interchangeably with *(Rarray+idx) Are arrays of structures passed by value or reference? struct rectangle * ptinrect(struct point p, struct rectangle *r, int n) { int i; for (i = 0; i < n; i++) { if (p.x >= r[i].pt1.x && p.x < r[i].pt2.x && p.y >= r[i].pt1.y && p.y < r[i].pt2.y) return(&r[i]); `} return((struct rectangle *) 0); } struct rectangle Rarray[N]; ptinrect(p,Rarray,N);

53 – 53 – Exercise Given these variables: struct { unsigned int is_keyword : 1; unsigned int is_extern : 1 ; unsigned int is_static : 1; }flags1; unsigned int flags2; Write an expression that is true if the field is_static is set, using the bit field notation on flags1, and also using bitwise operators on flags2.

54 – 54 – Accessing Elements within Array Compute offset from start of array Compute 12*i as 4*(i+2i) Access element according to its offset within structure Offset by 8 Assembler gives displacement as a + 8 a[0] a+0 a[i] a+12i short get_j(int idx) { return a[idx].j; } # %eax = idx leal (%eax,%eax,2),%eax # 3*idx movswl a+8(,%eax,4),%eax a+12ia+12i+8 struct S6 { short i; float v; short j; } a[10]; a[i].ia[i].ja[i].v

55 – 55 – Pointers point to memory locations Location determined based on what it points to Stack Local variables Heap Dynamically allocated data Global program data Statically allocated data Program code Program, libraries, and operating system

56 – 56 – Example #include #include int x=1; int func(int* i) { return (i+1) }; main(){ int *a; int *a; int b=0; int b=0; int (*f)(); int (*f)(); a = (int *) malloc(sizeof(int)); a = (int *) malloc(sizeof(int)); printf("&x is global: %p\n",&x); printf("&x is global: %p\n",&x); printf("a on heap: %p\n",a); printf("a on heap: %p\n",a); printf("&b on stack: %p\n",&b); printf("&b on stack: %p\n",&b); f = func; f = func; printf("f in prog code: %p\n",f); printf("f in prog code: %p\n",f);}

57 – 57 – Putting it together struct str { int t; char v; }; union uni { int t; char v; }; int g=15; int test() { int x = 2; int x = 2; fun(&x); fun(&x);} void fun(int *xp) { void (*f)(int*) = fun; void (*f)(int*) = fun; struct str s = {1,’a’}; struct str s = {1,’a’}; union uni *up = (union uni *) union uni *up = (union uni *) malloc(sizeof(union uni)); malloc(sizeof(union uni)); int *ip[2] = {xp, &g}; int *ip[2] = {xp, &g}; up->v = s.v+1; up->v = s.v+1; if (--(*xp) > 0) if (--(*xp) > 0) f(xp); f(xp);} &g, &x, &fun, &s, up, xp, f

58 – 58 – Putting it together struct str { int t; char v; }; char v; }; union uni { int t; char v; }; char v; }; int g=15; int test() { int x = 2; int x = 2; fun(&x); } fun(&x); } void fun(int *xp) { void (*f)(int*) = fun; void (*f)(int*) = fun; struct str s = {1,’a’}; struct str s = {1,’a’}; union uni *up = (union uni *) union uni *up = (union uni *) malloc(sizeof(union uni)); malloc(sizeof(union uni)); int *ip[2] = {xp, &g}; int *ip[2] = {xp, &g}; up->v = s.v+1; up->v = s.v+1; printf(“ip = %p,*ip = %p,**ip=%d\n”, printf(“ip = %p,*ip = %p,**ip=%d\n”, ip, *ip, **ip); ip, *ip, **ip); printf(“ip+1=%p,ip[1]=%p,*ip[1]=%d\n”, printf(“ip+1=%p,ip[1]=%p,*ip[1]=%d\n”, ip+1, ip[1], *ip[1]); ip+1, ip[1], *ip[1]); printf(“&s.v=%p,s.v=%c\n”,&s.v,s.v); printf(“&s.v=%p,s.v=%c\n”,&s.v,s.v); printf(“&up->v = %p,up->v = %c\n”, printf(“&up->v = %p,up->v = %c\n”, &up->v, up->v); &up->v, up->v); printf(“f=%p\n\n”,f); printf(“f=%p\n\n”,f); if (--(*xp) > 0) if (--(*xp) > 0) f(xp); f(xp);} First invocation: fun(&x) ip=0xbfffefa8,*ip=0xbfffefe4,**ip=2 ip+1=0xbfffefac,ip[1]=0x804965c,*ip[1]=15&s.v=0xbfffefb4,s.v=‘a’&up->v=0x ,up->v=‘b’f=0x What addresses correspond to… o stack locations o heap locations o global program data storage o program executable code

59 – 59 – Putting it together struct str { int t; char v; }; char v; }; union uni { int t; char v; }; char v; }; int g=15; int test() { int x = 2; int x = 2; fun(&x); } fun(&x); } void fun(int *xp) { void (*f)(int*) = fun; void (*f)(int*) = fun; struct str s = {1,’a’}; struct str s = {1,’a’}; union uni *up = (union uni *) union uni *up = (union uni *) malloc(sizeof(union uni)); malloc(sizeof(union uni)); int *ip[2] = {xp, &g}; int *ip[2] = {xp, &g}; up->v = s.v+1; up->v = s.v+1; printf(“ip = %p,*ip = %p,**ip=%d\n”, printf(“ip = %p,*ip = %p,**ip=%d\n”, ip, *ip, **ip); ip, *ip, **ip); printf(“ip+1=%p,ip[1]=%p,*ip[1]=%d\n”, printf(“ip+1=%p,ip[1]=%p,*ip[1]=%d\n”, ip+1, ip[1], *ip[1]); ip+1, ip[1], *ip[1]); printf(“&s.v=%p,s.v=%c\n”,&s.v,s.v); printf(“&s.v=%p,s.v=%c\n”,&s.v,s.v); printf(“&up->v = %p,up->v = %c\n”, printf(“&up->v = %p,up->v = %c\n”, &up->v, up->v); &up->v, up->v); printf(“f=%p\n\n”,f); printf(“f=%p\n\n”,f); if (--(*xp) > 0) if (--(*xp) > 0) f(xp); f(xp);} First invocation: fun(&x) ip=0xbfffefa8,*ip=0xbfffefe4,**ip=2 ip+1=0xbfffefac,ip[1]=0x804965c,*ip[1]=15&s.v=0xbfffefb4,s.v=‘a’&up->v=0x ,up->v=‘b’f=0x Second invocation: f(xp) ip=0xbfffef68,*ip=0xbfffefe4,**ip=1ip+1=0xbfffef6c,ip[1]=0x804965c,*ip[1]=15&s.v=bfffef74,s.v=‘a’&up->v=0x ,up->v=‘b’f=0x

60 – 60 – CS 201 Embedded Assembly

61 – 61 – Assembly in C Motivation Performance Access to special processor instructions or registers (e.g. cycle counters) Mechanisms specific to processor architecture (x86) and compiler (gcc) Must rewrite for other processors and compilers Two forms Basic: asm ( code-string ); Extended: asm ( code-string [ : output-list [ : input-list [ : overwrite-list ] ] ] );

62 – 62 – Basic Inline Assembly Implement ok_smul(int x, int y, int *dest) Calculate x*y and put result at dest Return 1 if multiplication does not overflow and 0 otherwise Use setae instruction to get condition code setae D (D <- ~CF)Strategy %eax stores return value Declare result and use it to store status code in %eax int ok_smul1(int x, int y, int *dest) { int result = 0; *dest = x*y; asm(“setae %al”); return result; }

63 – 63 – Basic Inline Assembly Code does not work! Return result in %eax Want to set result using setae instruction beforehand Compiler does not know you want to link these two (i.e. int result and %eax ) int ok_smul1(int x, int y, int *dest) { int result = 0; *dest = x*y; asm(“setae %al”); return result; }

64 – 64 – Extended form asm asm ( code-string [ : output-list [ : input-list [ : overwrite-list ] ] ] ); Allows you to bind registers to program values Code-string Sequence of assembly separated by “;” Output-list: get results from embedded assembly to C variables Tell assembler where to put result and what registers to use “=r” (x) : dynamically assign a register with output for variable “x” Specific registers may be used via their letter “=a” (x) : use %eax for variable x Separated by “,” if more than one output

65 – 65 – Extended form asm asm ( code-string [ : output-list [ : input-list [ : overwrite-list ] ] ] ); Input-list: pass values from C variables to embedded assembly Tell assembler where to get operands and what registers to use “r” (x) : dynamically assign a register to hold variable “x” Specific registers may be used via their letter – “a” (x) : read in variable x into %eax Overwrite-list: to write to registers Tell assembler what registers will be overwritten in embedded code Allows assembler to Arrange to save data it had in those registers Avoid using those registers

66 – 66 – Extended form asm Code-string Assembler Specific registers % Input and output operands Aliased via % Ordered in output list, then input list %0, %1, %2, etc. Output list Assembler assigns a register to store result Compiler adds code to save register to memory Overwrite list Compiler saves %ebx or avoids using %ebx in code int ok_smul3(int x, int y, int *dest) { int result; *dest = x*y; /* Insert following assembly setae %bl movzbl %bl,result */ asm(“setae %bl; movzbl %bl,%0” : “=r” (result) : : “%ebx” ); return result; }

67 – 67 – Extended form asm Unsigned multiplication example int ok_umul(unsigned x, unsigned y, unsigned *dest) { int result; /* movl x, %eax mull y movl %eax, *dest setae %dl movzbl %dl, result */ asm(“movl %2,%eax; mull %3; movl %eax,%0; setae %dl; movzbl %dl,%1” : “=r” (*dest), “=r” (result) : “r” (x), “r” (y) : “%eax”, “%edx” ); return result; }

68 – 68 – Problem What is the output of the following code? #include int myasm(int x, int y) { int result; asm("movl %1,%ebx; movl %2,%ecx; sall %cl,%ebx; movl %ebx,%0" : "=r" (result) : "r" (x), "r" (y) : "%ebx", "%ecx" ); return result; } main() { int k; k = myasm(2,3); printf("%d\n",k); }

69 – 69 – Extended form asm Something more useful rdtsc = read timestamp counter (Pentium) Reads 64-bit timestamp counter into %edx:%eax Accessed via asm Key code Combine into a union and treat as a 64-bit quantity unsigned int lo, hi; asm(“rdtsc”: “=a” (lo), “=d” (hi) );


Download ppt "CS 201 Structures Pointers. – 2 – Structures A structure is a complex data type Defined by the programmer Keeps together pertinent information of an object."

Similar presentations


Ads by Google