Chapter7 - Chapter 7: Data Structures EEC 70 Fall 2010...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 7: Data Structures EEC 70 Fall 2010 Professor Kent Wilken 1 Memory Memory is a linear array of bytes, each byte having its own address byte 7 ... 0 0 1 2 3 ... 2 Memory, Characters When data is declared, the data are placed in consecutive memory locations placed .data char1: char2: char3: char4: .byte .byte .byte .byte ‘!’ ‘&’ ‘i’ ‘H’ ! & i H 3 Memory, Characters (cont.) Memory, Characters at two memory locations are fundamentally unrelated (have no ‘connections’) • Any relationship depends on how the Any characters are accessed by the program: characters putc char4 putc char3 putc char1 output is “Hi!”, the three characters form a output the string on the terminal, as associated by the program program 4 Memory, Integers 32-bit integers are stored in memory as 4 32 bit consecutive bytes, that are related. are • Some computers store bytes starting with the most Some significant byte, big endian; endian • Some computers store bytes starting with the least Some significant byte, little endian; some allow both endian E.g, 0x87654321 87 65 43 21 Big Endian 21 43 65 87 Little Endian 5 Etymology of “Endian” Etymology Term comes from the novel Gulliver's Travels by Jonathan Swift Travels by The Lilliputians, being very small, had Lilliputians being correspondingly small political problems: correspondingly • the Big-Endian political party favored eating the Big political their soft-boiled eggs from the more rounded their boiled end (the big end) end • the Little-Endian party favored eating their the Little party eggs from the less rounded end (the little end) eggs 6 Accessing Memory SAL accesses bytes in memory using the array m[ ], which represents memory m[ • Same as ($Rx) operand in MAL m[i] refers to the contents of memory at the address contained in integer variable i address • E.g., m[123] refers to the contents of memory at E.g., address 123. address We can do arithmetic on an address variable: We move A, m[i] add i, i, 1 move B, m[i] move # B gets the character in memory that # follows the character in A follows 7 Accessing Memory Example We can easily create our own puts subroutine puts .data prompt: string: save_addr: outchar: .ascii “Good Morning!” .ascii .word # address of string to output .word # saves subroutine return address .byte # temporary character variable .byte temporary .text .text L1: la string, prompt la la save_address, L1 la b my_puts done # pass the string address # save return address my_puts: move outchar,m[string] # get next char from memory beqz outchar, leave # exit is char is null putc outchar # output the character add string, string, 1 # point to next character b my_puts my_puts leave: b (save_addr) leave: 8 Memory, Integers (cont.) Each byte in an integer has a separate address. What is the address of the integer as a whole? What • By convention, the smallest address MSB for big endian, LSB for little endian. MSB Most processors require or prefer that integers prefer that start at addresses that are multiples of 4, aligned aligned • Makes memory system design simpler, see EEC170. SAL uses M[ ] memory array for accessing integers M[ memory or floating point or • M[ ] Implies four consecutive bytes are accessed • Integers accessed using M[ ] must be aligned 9 Arrays Arrays are a high-level language construct. Assembly Arrays level language, machine hardware has no notion of arrays. language, Properties of arrays: Properties • Each element is the same size (char = 1 byte, int = 4 bytes, etc.) • Elements are stored in consecutive memory locations, with Elements first element stored at the smallest memory address first An extension to SAL data directive allows for arrays of fundamental elements: byte_array: .byte byte_array .byte 0:100 # allocate space of a 100 element # character array character # each character initialized to 0 10 Array Accesses Software must convert array index into memory address to access correct array element: address • Assume first index is zero: Address of element i = first_element_address + Address first_element_address (element_size x index) (element_size Example: access byte_array[17] la i, byte_array add i, i, 17 move char1, m[i] move m[i # get address of first element # add element offset, 17 x 1 # copy the element • Now don’t assume first index is zero: Address of element i = first_element_address + Address (element_size x (index - first_index)) first_index)) 11 Integer Arrays Similar to character arrays, except size of element is 4 bytes: is integer_array .word 0:100 or integer_array .byte 0:400 Example: access integer_array[17], assume first index is 0 la i, integer_array sll offset, 17, 2 add i, i, offset move int1, M[i] move M[i # get address of first element # compute element offset, 17 x 4 # compute element address # copy element 12 Arrays of Structures Arrays of structures can be created using .space directive to allocate space for array directive • .space is like .byte, .word, and .float but does not space initialize the memory initialize Consider example of student record: Consider last_name (max 12 characters) last_name student_id (1 integer) • student_array: .space 1600 # space for 100 elements Example: access the id of the 18th student, assume first Example: 18th index is 0 la i, student_array sll offset, 17, 4 add i, i, offset add i, i, 12 move int1, M[i] # get address of first element # compute element offset, 17 x 16 # compute element address # 12 is offset of id within record # get the id of the 18th student 13 Two Dimensional Arrays Memory is a one-dimensional array. How can we Memory dimensional create a two-D array? create • By slicing rows or columns By slicing • Row Major Order takes slices by rows, and then orders the takes element in 1-D memory by row element 0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 2,3 3,0 3,1 3,2 3,3 0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 14 Row Major Order Memory Addressing two_d_int_array .space 64 # for a 4 x 4 int array To access an array element (assuming starting element is [0,0]), we start with the base address of the array we • We then move to the start of the row we are interested in: We move we row_index x size_of_row is the number of elements we skip over row_index size_of_row = (elements/row) x size_of_element size_of_row • Next, move to the element within the row: Next, move column_index x size_of_element Array address is: base_address + (row_index x size_of_row) + column_index x size_of_element • Example: element 2,3 address is: two_d_int_array+ (2 x 16 bytes) + (3 x 4 bytes) = two_d_int_array+ 44 15 Column Major Order Similar to row major, except elements are sliced by column rather than row sliced 0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 2,3 3,0 3,1 3,2 3,3 0,0 1,0 2,0 3,0 0,1 1,1 2,1 3,1 0,2 1,2 2,2 16 Column Major Order Memory Addressing To covert a column major index to a memory address (assuming the starting index is [0,0]): index • Start with the base address • Add: column_index x size_of_column Add: column_index size_of_column size_of_column = column_dimension x element_size size_of_column column_dimension element_size • Add: row_index x size of element Add: row_index 17 Stacks Many programs need a data structure that stores data in the reverse order that it is used. data Often the amount of data is not known until the program is executed program Stack is a data structure that solves both problems Stack Stack data structure has the analogy to a stack of dishes dishes • the last item put on the stack is the first one removed Stack is an abstract data structure that is implemented with assembly language instructions in MIPS in 18 Stack Components Stack consists of: Stack • A region of memory memory region can be bounded or unbounded memory Bounded: Bounded: Unbounded: .data .data mystack: .space 100 .data .text stack • A Stack Pointer address variable (sp) that always points to Stack the element on the top of the stack, or always points the empty location just above the stack: empty sp sp item3 item2 item1 item3 item2 item1 19 Stack Operations Four operations are performed on stacks: Four • Push a new element onto the top of the stack element is written to next location, sp is advanced one location location sp item3 item2 item1 sp item2 item1 • move M[sp],A add sp, sp, -4 add Pop the element off the top of the stack Top element is read, sp is backed up one memory location. Element was logically deleted from stack, but is not erased. Will be overwritten on next push not sp item3 item2 item1 sp item3 item2 item1 add sp, sp, 4 add move B, M[sp] move 20 Stack Operations (cont.) Read the ith element relative to top of stack Read add temp, sp, 16 move A,M[temp] on the stack on # read the fourth element read Write the ith element relative to the top of Write the stack stack add temp, sp, 28 add move M[temp],B move on the stack on # write the seventh element write 21 Stack Growth Stacks can grow up (increasing memory addresses) or down (decreasing memory addresses) addresses) • growth direction often makes no difference Up Down sp 100 104 item2 108 item1 112 sp item1 100 item2 104 108 112 22 Example Stack Use Converting integer to characters: simplest conversion uses repetitive division by 10, produces least significant character digit first produces • But need to print least significant character last. But One answer: stack the characters One while integer <> 0 digit = integer mod 10 char = digit + 48 push char onto stack (element size = byte) integer = integer div 10 while stack is not empty pop char output char 23 Stack Implementation For fixed size, stack growing toward high numbered memory: memory: my_stack: my_stack: sp: • .space .space .word 200 my_stack stack pointer is statically initialized to first stack location. For For dynamic initialization: dynamic la sp, my_stack For fixed size, stack growing toward low numbered memory: For my_stack: my_stack: sp: .space .space .word 200 #static initialization not #possible in SAL la sp, my_stack add sp, sp, 196 24 Empty/Full Stacks It is invalid to pop an element from an empty stack stack • Also dangerous, because next push will overwrite another Also part of the program, or a part of another program part 100 104 108 112 It is invalid and dangerous to push to a full stack It item1 item2 item3 item4 100 104 108 112 116 25 Full/Empty Checks To avoid such problems, check stack for empty before pop: before la first, stack # compute first stack location # (only done once) ... ble sp, first, bad_pop # if sp <= first, outside stack area Check stack for full before push: Check add last, first, size_of_stack # compute first location past # stack end (only done once) ... bgt sp, last, bad_push # if sp > last, sp is past # end of stack area 26 Queues A queue is a data structure where the first element inserted is the next element to remove inserted • First In First Out (FIFO) Queue components: Queue • A region of memory (usually bounded) • .data myqueue: .space 100 Two address variables that are pointers to head and tail of the Two queue queue .data tail: .word # holds address of location after more recent holds # element element head: .word # holds address of oldest element head tail item1 100 item2 104 item3 108 112 27 Queue Operations Enqueue puts a new element at the tail of Enqueue puts the queue, advances the tail pointer: the head item1 item2 head tail item1 item2 item3 move M[tail],A add tail, tail, 4 tail Dequeue logically removes the element Dequeue logically at the head of the queue, advances the head pointer: head head tail item1 item2 item3 head item1 item2 item3 move B,M[head] add head, head, 4 tail 28 Queue Growth Queue will quickly run off the end of its allocated memory. Solution: Circular Queue Circular • when we reach the end, wrap around to the beginning: head item1 item2 tail • tail head item1 item2 item3 Requires an extra check on enqueue and dequeue: enqueue: cont: move M[tail],A add tail, tail, 4 ble tail, last, cont # check if past end move tail, first # if so, wrap around move if <next instruction> 29 Queue Growth (cont.) Extra check for dequeue: Extra cont: move B, M[head] add head, head, 4 ble head, last, cont # check if past end move head, first # if so, wrap around <next instruction> item5 item6 tail head head item5 item6 tail item4 item4 30 Empty/Full Queues It is invalid to enqueue to a full queue, dequeue from an empty queue. How to detect full, empty? from A queue is empty when the tail pointer equals the headpointer: headpointer: head tail beq tail, head, bad_dequeue A queue is full when, if the tail pointer is advanced, it would equal the head pointer advanced, item3 tail head item1 item2 31 Empty/Full Queues (cont.) Enqueue operation, with check for full, becomes: becomes: cont: add temp, tail, 4 blt temp, last, cont move temp, first move beq temp, head, bad_enqueue beq move M[tail],A move tail, temp move # check if past end # if so, wrap around if # if new tail = head, queue is full if # else, enqueue is ok, do it. # advance tail pointer advance 32 ...
View Full Document

This note was uploaded on 10/07/2011 for the course EEC 70 taught by Professor Wilken during the Fall '05 term at UC Davis.

Ask a homework question - tutors are online