CSC 3210 Computer Organization and Programming Georgia State University March 12, 2015 This lecture Plan for the lecture: Recap: Memory, The stack, The frame pointer Defining stack Variable Offsets Example gdb examine memory 1
Data types C Type SPARC Bits Unsigned Signed char byte 8 0, 255-128, 127 short half 16 0, 65,535-32,768, 32,767 int, long word 32 0, 4.294x10 9 2.147 x 10 9 All memory references must be aligned x byte quantities must begin in an address divisible by x Example int a, b; char c1; int c, d; //automatic variables int x, y, z; //use register for(z = 1; z < x+y;z++){ for(a = z; a>=z*y; a -= 10){ d = a + z; c1 = d * b; c = a + y/ z; } } 2
Memory Allocation and the Stack Automatic variables near top of memory = the Stack Stack has LIFO property Register %o6 holds the address of the last element placed on the stack = the stack pointer %sp More about the stack The stack grows downward to increase stack space, subtract from stack pointer sub %sp, 64, %sp 0x0000 The stack must be double word aligned %sp -> the stack Top of stack 0xf8000000 3
Chopping Aligning the Stack The address in %sp must be divisible by 8 Clear lowest three bits by using the and operation Add a chopped negative # to increase size add add %sp, -94 & 0xfffffff8, %sp %sp, -94 & -8, %sp Results in 96 being subtracted from %sp 4
The Frame Pointer The value for %sp is not constant So it is difficult to reference a variable s location by using %sp The frame pointer, %fp = %i6, stores a copy of %sp before it is changed The save instruction performs addition and updates %fp Example using %fp Want to add 92 extra bytes and store five 4- byte variables %sp: save %sp, (-92 (5*4))) & -8, %sp 92 extra bytes a4: %fp-20: a3: %fp-16: a2: %fp-12: a1: %fp-8: a0: %fp-4: 5
Addressing Variables Load and Store operations are the only instructions that reference memory Both instructions take two operands One memory location, and one register Can access memory using different data types (byte, half word, word, double word) Load Instructions Mnemonic ldsb ldub ldsh lduh ld ldd Operation Load signed byte, propagate sign left in register Load unsigned byte, clear high 24 bits of register Load signed halfword, propogate sign left in register Load unsigned halfword, clear high 16 bits of register Load word Load double, reg. # even, first 4 bytes into reg. n, next 4 into reg. n + 1 6
Load Instruction Format ld [memory location], reg rd ld [%fp 4], %l1!a0 into %l1 ld [%fp 8], %l2!a1 into %l2 ld [%fp 16], %l4!a3 into %l4 Note: Memory location argument can be a register, register + immediate, or register + register Store Instructions Mnemonic stb sth st std Operation Store low byte of register, bits 0-7, into memory Store low two bytes of register, bits 0-15 into memory Store register Store double, reg. # even, first 4 bytes from reg. n, next 4 from reg. n + 1 st reg rs, [memory location] st %l1, [%fp 4]!%l1 into a0 7
Problems with Stack Variable Offsets Define the constants symbolically: define(a0_s, -4) ld [%fp + a0_s], %l1 define(a1_s, -8) ld [%fp + a1_s], %l2 define(a2_s, -12) ld [%fp + a2_s], %l3 but still have to compute the offsets a0_s = -4 a1_s = -8 a2_s = -12 a3_s = -16.global main main: save %sp, (-92 + -16 ) & -8, %sp ld [%fs + a0_s], %l1! evaluated by the assembler ld [%fs + a1_s], %l2 ld [%fs + a2_s], %l3 8
An Example Using Macros define(`local_var, `define(last_sym, 0) ) define(`var, `define(`last_sym, eval(last_sym-$2))$1 = last_sym ) local_var var(a0_s, 4)!a0_s = -4 var(a1_s, 4)!a1_s = -8.global main main: save %sp, (-92 + last_sym) & -8, %sp ld [%fp + a0_s], %l1 ld [%fp + a1_s], %l2 Data types C Type SPARC Bits Unsigned Signed char byte 8 0, 255-128, 127 short half 16 0, 65,535-32,768, 32,767 int, long word 32 0, 4.294x10 9 2.147 x 10 9 All memory references must be aligned x byte quantities must begin in an address divisible by x 9
But we still have problems local_var var(a_s, 4)!a_s = -4 var(b_s, 4)!b_s = -8 var(ch_s, 1)!ch_s = -9 var(c_s, 2)!c_s = -11 var(d_s, 4)!d_s = -15 ldsh [%fp + c_s], %o0! -11 ld [%fp + d_s], %o1! -15 Defining Stack Variable Offsets Define macros to compute the offsets and make the definitions define(local_var, `define(last_sym, 0) ') define(`var', `define(`last_sym', eval((last_sym - $2 & -$2)) $1 = last_sym') 10
Aligning Variables define(`var', `define(`last_sym', eval((last_sym - $2 & -$2)) $1 = last_sym') a_s = -4 b_s = -8 ch_s = -9 c_s = -12 d_s = -16 a_s = -4 b_s = -8 ch_s = -9 c_s = -11 d_s = -15 Aligning Variables %fp - 16 d a_s = -4 b_s = -8 ch_s = -9 c_s = -12 d_s = -16 %fp - 12 %fp - 9 %fp - 8 c ch b %fp - 4 a %fp 11
gdb examine memory the command x (for "examine") to examine memory in any of several formats independently of your program's data types. x/nfu addr n, the repeat count f, the display format `The default is `d' (decimal) initially `x' (hexadecimal) u, the unit size The unit size is any of b Bytes. h Halfwords (two bytes). w Words (four bytes). This is the initial default. g Giant words (eight bytes, double words). Example x/w $fp 4 x/b $fp - 5 Example int a; char ch; int b; int x, y; //memory //register x = 20; y = 30; a = x + y; b = x y; ch = a * b; 12
define(`local_var', `!local variables define(`last_sym', 0)') define(`var', `define(`last_sym', eval((last_sym - $2) & -$2)) $1 = last_sym') local_var var(a_s, 4) var(ch_s, 1) var(b_s, 4) define(x_r, l0) define(y_r, l1).global main main: save %sp, (-92 + last_sym) & -8, %sp mov 20, %x_r mov 30, %y_r add %x_r, %y_r, %o0 st %o0, [%fp + a_s] sub %x_r, %y_r, %o0 st %o0, [%fp + b_s] ld [%fp + a_s], %o0 ld [%fp + b_s], %o1 call.mul nop stb %o0, [%fp + ch_s] result: mov 1, %g1 ta 0 int a; char ch; int b; int x, y; x = 20; y = 30; a = x + y; b = x y; ch = a * b; 13