CLASS 6

Some Basic Instructions in Sparc Assembly

Single Operand Instructions

clr r1 (clear register r1)

Two Operand Instructions

mov r1(or c), r2 

Three Operand Instructions

add r1, r2(or c), r3
sub r1, r2(or c), r3

Problem - No instruction in Sparc for multiplication.

For multiplying two numbers, i.e. for a = b * c ,

mov b, %o0
mov c, %o1
call  .mul  ! (result stored in register %o0)
nop	    ! delay slot, discussed later

Similarly for dividing two numbers, i.e. for a = b / c ,

mov b, %o0
mov c, %o1
call  .div  ! (result stored in register %o0)
nop         ! delay slot, discussed later

Pipelining in Sparc Architecture

In the SPARC chip, designers used special logic to make the pipeline appear to be only two-deep. There are two program counters, %pc and %npc. %npc is always copied to %pc; %npc is sometimes incremented by four, other times (in case of a branch, call, return, etc.) it is modified. This occurs on each cycle. One can understand how delay slots work by tracking the contents of pc and npc. Because there are TWO program counters, the effective depth of the SPARC pipeline is 2.

The net effect is that instructions after branches and calls are always executed. They are called "delay slot" instructions.

Clearly, one can always put NOPS in there. But that would just waste one cycle, as nothing would be executed in that cycle. How can we make better use of the delay slot? Well, it turns out that there is almost always an instruction that can be put in the delay slot without changing the logic of the program. The instruction cannot be allowed to modify data that affects the branch, or else there will be an error.

To fill a delay slot, find an instruction that can be placed immediately before the branch, but doesn't affect the condition tested by the branch.

As the instruction in the pipeline always executed, problem in case of a BRANCH instruction (the the value of program counter (%pc) changes, so the value of next program counter (%npc) should also change.

As a result, we use a nop instruction after the branch instruction to avoid any errors.

nop - instruction that is executed but does nothing

Our first assembly program in further detail...

Recall the program first.s discussed in the previous class. Its given here for your convenience.

/* first.s */ /* This programs computes the expression: y = (x - 1) * (x - 7) / (x -13) for x = 9 */ .global _main _main: save %sp, -64, %sp mov 9, %l0 !initialize x sub %l0, 1, %o0 !(x - 1) into %o0 sub %l0, 7, %o1 !(x - 7) into %o1 call .mul nop !result in %o0 sub %l0, 11, %o1 !(x - 11) into %o1, the divisor call .div nop !result in %o0 mov %o0, %l1 !store it in y mov 1, %g1 !trap dispatch ta 0 !trap to system
When we ran the program last time, we did not get any input/output, so how do we find out if the program ran successfully or not? Well, like I said last time, we make use of a debugger. I'll use the gdb debugger for this course, so you need to familiarize yourself with it.

The gdb DEBUGGER

Some commonly used commands...

gdb filename (to open up the file in gdb)

e.g. gdb expr (to open up file expr which is executable)

r (to run the file, no argument required)

b (to set a break point)

e.g. b main (set breakpoint to main)
b *& main + 20 (set breakpoint to address of main + 20)

x (examine memory at the address)

e.g. x $pc (to examine contents of program counter)

ni (execute the instruction, go to next instruction, no arguments)

x/i $pc (to print value in register %pc, if multiple times, then press enter again and again, and it displays the succeeding values.)

Note: In gdb, registers are preceded by $ (and not %)

p (print the contents of a register)

e.g. p $l0
p $o1

display/i %pc (print value of program counter every time a command is executed)

q (quit the gdb debugger)

disassemble (to print all the instructions of the current function)

c (to continue execution after halting at a breakpoint)

commands n (to do commands whenevr breakpoint n is reached)

e.g. If we want to do a execute a certain set of commands every time we reach breakpoint 2 in our code, we write:
 commands 2
 p $l1
 c 
 end 

Setup file called .gdbinit
Place this file in Home Directory.

Typical Contents of .gdbinit:

        break main
        display/i $pc 
        r 

An example of a run session with gdb on file expr

colossus> gdb expr

GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details.

GDB 4.13 (sparc-sun-sunos4.1.3_U1),

Copyright 1994 Free Software Foundation, Inc...

(gdb) r // prompt for gdb

Starting program: /export/grad/tvohra/winter/240/temp/expr

(no debugging symbols found)...

Program exited with code 0370.

(gdb) b main

Breakpoint 1 at 0x2294

(gdb) r

Starting program: /export/grad/tvohra/winter/240/temp/expr

Breakpoint 1, 0x2294 in main ()

(gdb) x/i $pc //to examine memory, and execute instruction

0x2294 <main+4>: mov 9, %l0

(gdb) //return just repeats the previous command again

0x2298 <main+8>: sub %l0, 1, %o0

(gdb) x $pc // just view the contents of the address

0x2294 <main+4>: mov 9, %l0

(gdb) b *& main + 8

Breakpoint 2 at 0x2298

(gdb) c

Continuing

Breakpoint 2, 0x2298 in main()

(gdb) x $pc

0x2298 <main+8>: sub %l0, 1, %o0

(gdb) disassemble

Dump of assembler code for function main:
0x2290 <main>:  save  %sp, -64, %sp
0x2294 <main+4>:        mov  9, %l0
0x2298 <main+8>:        sub  %l0, 1, %o0
0x229c <main+12>:       sub  %l0, 7, %o1
0x22a0 <main+16>:       call  0x4090 <.mul>
0x22a4 <main+20>:       nop 
0x22a8 <main+24>:       sub  %l0, 0xb, %o1
0x22ac <main+28>:       call  0x409c <.div>
0x22b0 <main+32>:       nop 
0x22b4 <main+36>:       mov  %o0, %l1
0x22b8 <main+40>:       mov  1, %g1
0x22bc <main+44>:       ta  0
End of assembler dump.

(gdb) b *& main + 40

Breakpoint 3 at 0x22b8

(gdb) c

Continuing.

Breakpoint 3, 0x22b8 in main ()

(gdb) display/i $pc

  x/i $pc  0x22b8 <main+40>:   mov  1, %g1

(gdb) ni

0x22bc in main ()

  x/i $pc  0x22bc <main+44>:   ta  0

(gdb) ni

Program exited with code 0370.

(gdb) q

colossus> // back to unix prompt

For more details on using the GDB debugger, you can view the file gdb.ps in directory /classes/cs240/common (Warning : Please do not print a copy of the entire manual, as it is about 200 pages long, and most of the information is not useful for most of you.) To download/view the quick reference card for GDB, click here. You can find the postscript version of this file also under /classes/cs240/common/gdb-refcard.ps.

For class 7 notes, click here

For more information, contact me at tvohra@mtu.edu