# xorpd assembly riddle 0x04

xorpd has some riddle-like pieces of assembly code here. In this post, I’ll analyze this one.

I present to you this marvelous one-line riddle:

`xor al,0x20`

What can we infer from this?

- It’s using
**al**register: a single byte it’s being used - 0x20 = 32 = 00100000

Now, let’s talk about **xor** a little. This is its truth table:

`input1 | input2 | result`

0 | 0 | 0

0 | 1 | 1

1 | 0 | 1

1 | 1 | 0

Analyzing the second column we can see that a **0** placed there will preserve the value of **input2 **and a **1** will flip its value instead:

`input1 | input2 | result`

0 | 0 | 0 ==> input2=0, input1=result

0 | 1 | 1 ==> input2=1, input1=!result

1 | 0 | 1 ==> input2=0, input1=result

1 | 1 | 0 ==> input2=1, input1=!result

That’s why **xor {regX},{regX} **is used a lot by compilers to zero out a register. Observe that any value XORed with itself is equal to 0. i.e: the operation **00110101 xor 00110101 **can be expressed like:

input1 | input2 | input1 xor input2

0 | 0 | 0

0 | 0 | 0

1 | 1 | 0

1 | 1 | 0

0 | 0 | 0

1 | 1 | 0

0 | 0 | 0

1 | 1 | 0 Basically every 0 is preserved and every 1 is flipped so we end up with all zeros as results

So, going back to our riddle. We can express what we know so far as:

al | 0x20 | xor al, 020

? | 0 | ?

? | 0 | ?

? | 1 | x ==> this bit will be flipped

? | 0 | ?

? | 0 | ?

? | 0 | ?

? | 0 | ?

? | 0 | ?As the only1in 0x20 is at bit n°6 that's the only bit that will flipped onal

How does this bit flip affects **al**? It will **add or subtract 32** (*0x20*) from al depending on **al**’s original value:

Case 1: Imagine al to be 0x0 = 0 = 00000000

al | 0x20 | xor al, 020

0 | 0 | 0

0 | 0 | 0

0 | 1 | 1

0 | 0 | 0

0 | 0 | 0

0 | 0 | 0

0 | 0 | 0

0 | 0 | 0result = 0x20 = 32 = 00100000Case 2: Imagine al to be 0xff = 255 = 11111111

al | 0x20 | xor al, 020

1 | 0 | 1

1 | 0 | 1

1 | 1 | 0

1 | 0 | 1

1 | 0 | 1

1 | 0 | 1

1 | 0 | 1

1 | 0 | 1result = 0xdf = 223 = 11000000

Let’s try some more values:

`al | 0x20 | xor al, 020`

0x00 | 0x20 | 0x20 = 00100000 = 32 = " "

0xff | 0x20 | 0xdf = 11011111 = 223 = (no ascii value)

0x41 | 0x20 | 0x61 = 01100001 = 97 = "a"

0x50 | 0x20 | 0xdf = 01110000 = 112 = "p"

0x61 | 0x20 | 0x41 = 01000001 = 65 = "A"

From this, it’s clear that values from ASCII letters in uppercase are converted to its lowercase counterpart and vice-versa. We can check this by calculating the distance between the boundary characters:

`Upper | lower | distance`

A | a | 0x41 - 0x61 = **0x20**

Z | z | 0x5a - 0x7a = **0x20**

So, long story short this single line of assembly performs a lowercase/uppercase ASCII conversion! isn’t that awesome?