1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Swaping in Assembly

Discussion in 'Assembly Language Programming (ALP) Forum' started by dsptl, Jul 1, 2009.

  1. dsptl

    dsptl New Member

    Joined:
    Jun 14, 2009
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    0
    How can you exchange(swap) the first bit and the last bit of register %o0 in Assembly?
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    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");		
    	}
    }
    
    Most of it is just a testbed for the calculation itself, which is just:
    Code:
    		if (reg>0 && reg&1 || reg<0 && !(reg&1))
    			reg ^= 0x80000001;
    
     
  3. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    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 
    
    And here's a hand coded one in 9 pseudocode instructions that uses one register for the two bits, and assumes that <<= shifts the carry flag C into bit 0 and bit 31 into C, and >>= works the same way, AND not only doesn't require C to be set to anything specific but preserves its value (u) throughout:

    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
    
    This can be reduced to 7 instructions if two consecutive <<=1's and >>=1's have exactly the same effect as a single <<=2 or >>=2. Note <<= and >>= are NOT equivalent to the C instructions because these shift a zero bit into the register and lose the bit that drops off the end.
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    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
    
     

Share This Page