Search code examples
c++assemblybitwise-operatorscpu-architecturebitwise-xor

XOR Operation C++/Assembly


This is a code that's doing XOR operations. The code is doing like x.bits.b = x.bits.c ^ x.bits.a What I want is that: x.bits.c = x.bits.a ^ x.bits.b

I tried to change all of "cl" values to "bl" and it did not work.

#include "stdafx.h"
int main()
{
typedef union {
    unsigned char BYTE;
    struct {
        unsigned char a : 1;
        unsigned char b : 3;
        unsigned char c : 4;
    }bits;
}un_X;

un_X x;

x.BYTE = 0xFE;
x.bits.a = 1;
x.bits.b = 0;
x.bits.c = 2;


printf("\n");
printf("BYTE = %X\n", x.BYTE);
printf("   a = %d\n", x.bits.a);
printf("   b = %d\n", x.bits.b);
printf("   c = %d\n", x.bits.c);



_asm {
    //unsigned char a = x.BYTE & 0x01;
    mov al, x.BYTE
    and al, 0x01
    // unsigned char c = (x.BYTE & 0xF0) >> 4;
    mov cl, x.BYTE
    and cl, 0xF0
    shr cl, 4
    //unsigned char b = c ^ a;
    xor al, cl
    // x.BYTE &= 0xF1; // 1111 0001
    mov dl, x.BYTE
    and dl, 0xF1
    // x.BYTE |= (b << 1);
    shl al, 1
    or dl, al
    mov x.BYTE, dl

}





printf("\n");
printf("BYTE = %X\n", x.BYTE);
printf("   a = %d\n", x.bits.a);
printf("   b = %d\n", x.bits.b);
printf("   c = %d\n", x.bits.c);

getchar();
return 0;
}

I expect to a and b is constant and c is variable.


Solution

  • When you use a bitwise AND with 0xF1 to clear out some bits of x.BYTE, then OR in the value of al shifted left by 1, the bits that get populated are the first three bits of c, aka the lower nibble of x.BYTE. This gives us:

    0001
     XOR
    0011
    ----
    0010
    

    Which has the value 2, explaining the output. As for b, since it occupies bits 1..4 of x.BYTE, and you want b to have the value zero, just do a bitwise AND on those bits:

     mov al, x.BYTE
     and al, 0x8F