# Computer Science 237 Computer Organization

### Williams College Fall 2006

Lecture 18: Saving Registers for Subroutine Calls, Building Memory
Date: October 23, 2006

#### Agenda

• Announcements
• No formal lab meeting this week
• Sequential logic lab due
• Last assembly programming lab out
• Saving registers: a protocol everyone must agree on
• A common method is to save registers you plan on using, before you use them Recall our array-based swap example:
```void swap(int a[], int i, int j)
{ register int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
```
Our assembly translation used a0, d0, d1, d2, d3, so we could save those on the stack before we use the registers, pop off and restore after:
```a = 8
i = 12
j = 14
move.l %d0,-(%sp)
move.l %d1,-(%sp)
move.l %d2,-(%sp)
move.l %d3,-(%sp)
move.l %a0,-(%sp)
....code for swap from before...
move.l (%sp)+,%a0
move.l (%sp)+,%d3
move.l (%sp)+,%d2
move.l (%sp)+,%d1
move.l (%sp)+,%d0
unlk   %a6
rts
```
Note that any order for pushing the registers works, as long as they are popped off in reverse order
• The movem.l instruction performs all of the push (or pop) instructions in a single call:
```swap: link  %a6,#0
movem.l #0x010f,-(%sp)
...
movem.l (%sp)+,#0xf080
unlk   %a6
rts
```
• No choice in order for pushing: a7..a0,d7..d0
• No choice in order for popping: d0..d7,a0..a7
• Low order bit is the first register to be transferred. Thus to push all registers, less a7, you would use: `#0x7fff`. To pop all registers, less a7, you would use: `#0xfffe`
• Unfortunately, the gcc compiler in the Palm environment does not abide by this protocol, and there is no way to do the right thing. Essentially, the view is to assume that every call will destroy every register, so don't depend on (or require) their continuity. (Why?)
• A work-around. Think about values you keep in registers. Push registers you wish to maintain on the stack before the call, pop them off after.
```| win.s: safely use d1 and highlight.
move.w  #0,%d1
loop: cmp.w #4,%d1
bge     endloop
| highlight could destroy d1, so
| we save it on the stack:
move.w  %d1,-(%sp)
| push parameters (3-i,i)
move.w  %d1,-(%sp)
move.w  #3,-(%sp)
sub.w   %d1,(%sp)
bsr     highlight
| stack contains remnants of params
| and saved d1.  d1 is junk.
| pop params, and restore d1