Swaping in Assembly
|
Light Poster
|
|
| 2Jul2009,03:07 | #1 |
|
How can you exchange(swap) the first bit and the last bit of register %o0 in Assembly?
|
|
Mentor
|
![]() |
| 2Jul2009,16:15 | #2 |
|
Here's a quick test program I wrote in C; compile to assembler to get the result for your specific hardware:
Code:
void swapbits()
{
for (int i=0; i<4; i++)
{
int reg=0, exp=0, reg1;
switch (i)
{
case 0: reg=0xffff0000; exp=0x7fff0001; break; // 1xx0 -> 0xx1
case 1: reg=0xffff0001; exp=0xffff0001; break; // 1xx1 -> 1xx1
case 2: reg=0x7fff0001; exp=0xffff0000; break; // 0xx1 -> 1xx0
case 3: reg=0x7fff0000; exp=0x7fff0000; break; // 0xx0 -> 0xx0
}
reg1=reg;
if (reg>0 && reg&1 || reg<0 && !(reg&1))
reg ^= 0x80000001;
printf("Swap 0x%04x, expect 0x%04x, result 0x%04x, %s\n", reg1, exp, reg,
(exp==reg) ? "OK" : "NOK");
}
}
Code:
if (reg>0 && reg&1 || reg<0 && !(reg&1)) reg ^= 0x80000001; |
|
Mentor
|
![]() |
| 3Jul2009,17:25 | #3 |
|
Here's another expression that doesn't use "if" statements and should execute in constant time regardless of the bit values, unlike the previous one. Execution in constant time is useful for programming embedded systems. With disassembly, as generated by Visual Studio 2008:
Code:
reg ^= (- ( (reg&0x00000001) ^ ((reg&0x80000000)>>31) )) & 0x80000001; 00413B6B mov eax,dword ptr [reg] 00413B6E and eax,1 00413B71 mov ecx,dword ptr [reg] 00413B74 and ecx,80000000h 00413B7A shr ecx,1Fh 00413B7D xor eax,ecx 00413B7F neg eax 00413B81 and eax,80000001h 00413B86 xor eax,dword ptr [reg] 00413B89 mov dword ptr [reg],eax Code:
reg1 reg2 C reg2=reg1; axxb axxb ; goal: reg1=bxxa reg1&=0110; 0xx0 u reg1>>=1; u0xx 0 reg2<<=1; xxb0 a reg1<<=1; 0xxa u reg1<<=1; xxau 0 reg2>>=1; 0xxb 0 reg2>>=1; 00xx b reg1>>=1; bxxa u |
|
Mentor
|
![]() |
| 3Jul2009,21:01 | #4 |
|
And here's one in just six (realised the &=0110 wasn't necessary):
Code:
reg2=reg1 axxb axxb u reg1<<=1 xxbu a reg2>>=1 aaxx b reg1>>=2 ubxx b reg2<<=1 axxb a reg1<<=1 bxxa u |

