clr r1 (clear register r1)
mov r1(or c), r2
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
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
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.
/* 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
Some commonly used commands...
e.g. gdb expr (to open up file expr which is executable)
commands 2 p $l1 c end
break main display/i $pc r
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...
Starting program: /export/grad/tvohra/winter/240/temp/expr
(no debugging symbols found)...
Program exited with code 0370.
Breakpoint 1 at 0x2294
Starting program: /export/grad/tvohra/winter/240/temp/expr
Breakpoint 1, 0x2294 in main ()
0x2294 <main+4>: mov 9, %l0
0x2298 <main+8>: sub %l0, 1, %o0
0x2294 <main+4>: mov 9, %l0
Breakpoint 2 at 0x2298
Continuing
Breakpoint 2, 0x2298 in main()
0x2298 <main+8>: sub %l0, 1, %o0
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.
Breakpoint 3 at 0x22b8
Continuing.
Breakpoint 3, 0x22b8 in main ()
x/i $pc 0x22b8 <main+40>: mov 1, %g1
0x22bc in main ()
x/i $pc 0x22bc <main+44>: ta 0
Program exited with code 0370.