Fog Creek Software
Discussion Board




Firmware Programmer Queston: Swapping Registers

Very interesting topics, but they all seem a little too astract for some of my colleages, in a world that is still Assembly language based.

This is why I came looking for questions to ask high level programmers.

A question posed to me was:

You are in a processor with only 2 registers (R0 and R1)
There is no user stack or other memory.

You have all the standard binary operators:
(shown here as 'C' operators )
*  /  %  +  –  << >> <  >  <=  >=  ==  !=  &  |  ^ &&  ||

Swap the values of the two registers.

Ken LaBar
Thursday, February 21, 2002

Although i have fairly small amount of programming experience, the following lines should do it:

Ro = Ro + R1  // Value 0 is set to the sum of both values
R1 = Ro - R1  // Value 1 is set to the sum minus value1, hence value 0
Ro = Ro - R1  // The sum is set to the sum minus value 0, hence value 1

This just switched the two variable's values (not sure if that's what you wanted)

Dave Schnizlein
Thursday, February 21, 2002

and yes, feel free to laugh at me for my gross mis-interpretation of that question

Dave Schnizlein
Thursday, February 21, 2002

XOR is the key.

R0 ^= R1;
R1 ^= R0;
R0 ^= R1;

for example:

R0=01101110
R1=10100101

after R0 ^= R1; R0=11001011
after R1 ^= R0; R1=01101110
after R0 ^= R1; R0=10100101

essentially, R0 holds both values for a moment, if you can imagine such a thing, before we split them apart again.

I don't know how to describe it better -- perhaps someone else can describe it more eloquently.

David Woodruff
Thursday, February 21, 2002

Wow you guys are good.

XOR is the key!!!

Although the addition, subtraction method does work in most cases, there are cases where the math can overflow and you loose bits.

Ken LaBar
Friday, February 22, 2002

The addition/subtraction method always works,
provided you always use variants that aren't affected
by the carry flag. (Which should be pretty much
implicit in using C-like notation for the operations!)

Let a,b be the initial contents of R0,R1. Then
the following equalities all hold *modulo 2^n*,
where n is your word length. Two n-bit quantities
that are equal modulo 2^n are equal. Game over.

After R0 = R0+R1: R0=a+b, R1=b
After R1= R0-R1: R0=a+b, R1=a
After R0 = R0-R1: R0=b, R1=a.

By the way, there are other solutions. For instance,

R0 = R0-R1 // a-b, b
R1 = R1+R0 // a-b, a
R0 = R1-R0 // b, a

Some processors might not let you do R1=R0-R1
(or R0=R1-R0) in a single instruction, by the way.
Also, XORing is likely to mess up only the zero flag,
whereas the add-and-subtract way will typically
scrobble them all. So the XOR approach is better,
but not because the add-and-subtract approach
doesn't work.

Gareth McCaughan
Sunday, March 10, 2002

If you like, you can do it in one line of source:
R0 ^= (R1 ^= (R0 ^= R1));
Then it's easy to make a SWAP() macro.
It's the sort of thing you either do all the time or you never do.  I've never written a program where I couldn't have another int on the stack.

Brian McKeever
Tuesday, April 02, 2002

*  Recent Topics

*  Fog Creek Home