plz explain AND,OR,XOR and TEST operations

Started by AssemblyBeginner, July 22, 2006, 10:39:28 AM

Previous topic - Next topic

AssemblyBeginner

hi i m asm beginer and want to know about these instructions more information with expalination.what i know about these each one i write.i thing this is not enough so plz guide me more regarding this.

a)AND

truth table
       
0 0 |0
0 1 |0
1 0 |0
1 1 |1

1.used for turning off unwanted bits(masking bits) (not understand)
2.used to clear registers(understand)
    and ax,00h   

b)OR

truth table
0 0 |0
0 1 |1
1 0 |1
1 1 |1

1.used to turn on bits(not understand)

c)XOR

truth table

0 0 |0
0 1 |1
1 0 |1
1 1 |0

1.used for toggling bits(turn on/off bits)(understand)


d)TEST ?...



i want to know more about AND,OR,XOR,TEST
plz tell me other usage of each will example with different situations

MichaelW

Here is a working example that uses AND to mask off bits, in this case so the lower 4 bits of BX can be used to index (address) a table of hex characters:

.data
    hexChars db "0123456789ABCDEF"
.code
; -------------------------------------------------------------
; This proc converts a word to a null-terminated 4-character
; hex string and stores the result in the specified buffer.
; -------------------------------------------------------------
w2hex proc c uses ax bx dx di src:WORD, npdest:WORD
    mov dx, src
    mov di, npdest
    add di, 3                 ; Set DI to end of buffer
    mov BYTE PTR [di+1], 0    ; Append trailing null
  @@:
    mov bx, dx                ; Copy current value into BX
    and bx, 0Fh               ; Mask off all but lower nibble
    mov al, hexChars[bx]      ; Load corresponding char into AL
    mov [di], al              ; Store in buffer
    shr dx, 4                 ; Shift next nibble into position
    dec di                    ; Adjust DI for next character
    cmp di, npdest            ; Repeat for all 4 characters
    jnb @B
    ret
w2hex endp


TEST works like AND, but the result is not stored in the destination operand, only in the flags. This is useful for determining if certain bits are set in a register or variable, without regard to the value of the other bits, and without changing the value in the register or variable. In this example, the jump would be taken if the most significant bit of AX were set, and the value in AX would not change:

test ax, 8000h
jnz  someLabel

If you used AND for this the value in AX would change if it were anything other than 0000 or 8000h. And you could not use CMP for this unless you knew the state of all the bits other than the most significant, because CMP would compare all of the bits.
eschew obfuscation

zooba

The truth tables you've shown are correct. Bits which are 1 are said to be 'on', 'set' or 'high'. Bits which are 0 are said to be 'off', 'clear' or 'low'. In assembly language, I prefer to use 'set' and 'clear', so I'll use those (it's a different story in electronics :wink )

For the purposes of this brief tutorial, assume A is a bit and B is a bit (their values don't matter and will change as we talk about them).

There are two ways of looking at how the bit-wise functions behave - by how both bits affect the result, or by how the second bit (B) affects the first bit (A).

View 1 (how both bits affect the result):

The AND function returns 1 if and only if both A and B are 1.
The OR function returns 1 if either of A or B are 1.
The XOR function returns 1 if either but not both of A or B are 1.

View 2 (how B affects A):

A AND 1 = A     (B=1 lets A pass through unchanged)
A AND 0 = 0     (B=0 makes A become zero)

A OR 1 = 1      (B=1 makes A become one)
A OR 0 = A      (B=0 lets A pass through unchanged)

A XOR 1 = NOT A (B=1 makes A toggle)
A XOR 0 = A     (B=0 lets A pass through unchanged)



These are for individual bits, which isn't particularly efficient. So we do lots at once. 8-bit processors do 8-bits at once, 16-bit ones can do 16-bits and 32-bit processors (like the Intel x86) can do 32-bits at once. Let's work with 8 bits for a while.

Our A and B from before are now going to be BYTEs, where a byte is a group of 8-bits. We'll also look at everything using view 2 from above, since it makes more sense in this context.

Using AND (note, this isn't assembly language, it's a demonstration):

A       = 10100101
B       = 00001111


We'll go through one bit at a time, starting from the right (also known at the LEAST significant bit or the LSB)

1 AND 1 = 1
0 AND 1 = 0
1 AND 1 = 1
0 AND 1 = 0
0 AND 0 = 0
1 AND 0 = 0
0 AND 0 = 0
1 AND 0 = 0


Now, we can put the result together and find out that:

A AND B = 00000101

Now, if we look at the values of A, B and A AND B next to each other, it should become clear why AND can be used to mask out bits:

A       = 10100101
B       = 00001111
A AND B = 00000101


Notice how the four leftmost bits of A have all become zero in the result and the four rightmost bits of A have all remained the same. In this way, we can clear some bits without affecting the others.

Let's have a look at OR, with the same values of A and B.

A       = 10100101
B       = 00001111
A OR B  = 10101111


This time, the four leftmost bits from A have all stayed the same, while the four rightmost bits are now 1. In this way, we can set some bits without affecting the others.

Finally, XOR:

A       = 10100101
B       = 00001111
A XOR B = 10101010


Now, the four leftmost bits have stayed the same as A, while the four rightmost bits are now the opposite of what they were in A. This way, we can toggle some bits without affecting the others.


Now, since the x86 can handle 32-bits at once (it can also do 8 and 16 bits but 32-bits is preferred), we're going to get pretty confused if we write in 1s and 0s the whole time. So we tend to use hexadecimal for ease (see http://en.wikipedia.org/wiki/Hexadecimal if you don't know hexadecimal, it's too much to teach for a forum post :wink )


Assembly language reinforces view two, in that the second value affects the first value. It does this because the first value you give an AND, OR or XOR command in assembly actually gets changed by the command. The instruction comes first, followed by the first value and then the second value.:

AND  EAX, 0000FFFFh     ; Set the upper 16-bits of EAX to zero, leave the rest
OR   ECX, 80000000h     ; Set the MOST significant bit of ECX to 1, leave the rest
XOR  EAX, EAX           ; Toggle all the bits in EAX which are 1, ie. set EAX to zero


To cut a long story short (and to answer your specific question about TEST), each of these set some flags which the computer can use to decide what to do. OR and XOR generally don't set any useful flags, but AND can be used to test if a certain bit was set or not (see Michael's second example below). However, in doing so the original value is destroyed. The TEST command does exactly the same thing as AND, except it doesn't store the result back into the first value. This way, you can TEST the same value over and over again without having to reload it.

Hope this has helped a little.

Cheers,

Zooba :U

AssemblyBeginner

thks MichaelW and Zooba for a g8t help

i bit confused i TEST operation plz explain with example

and how OR is useful in windows style operation as i read from wikipedia plz also explain with example

zooba

TEST can also be interpreted as a bit-test. You pass it two values and it returns 1 if any of the 1 bits match and zero if none of them match.

mov  al, 11010001b
test al,00010000b
jnz  BitWasSet
jz   BitWasNotSet


In this way, it is possible to use a 32-bit value to represent 32 boolean values (on/off, or true/false). If a bit is set, it is true. If a bit is clear, it is false. This way we can pass 32 values at once, saving time and space. Window styles work in this way. It makes much more sense to have each bit represent a style rather than requiring 32 seperate true/false values to be passed. I've shown already how AND or TEST can be used to isolate individual bits (both AND and TEST work the same, except AND will modify the first value while TEST doesn't), or clear some bits without affecting the rest. OR can be used to set some bits without affecting the rest.

mov  al, 10100000b
or   al, 00000111b
; now al = 10100111b


Effectively, OR is used to turn some bits on and AND is used to turn some bits off. Each window style constant is a value with one bit set*. By ORing the desired styles together, you end up with a single DWORD which represents the entire style** of the window/control. The internal Windows code will use TEST to see which styles you want and base its actions on those. This way, any combination of the flags is possible.

Since 1 is accepted to be true, ORing styles together indicates that each of those styles is desired. If a style is not ORed into the style value, its respective bit won't be set, using TEST will return 0 and the style won't be used.

There are a number of examples of Windows code on the forum and in the MASM32 package. If you are still having trouble, read through posts in The Campus (a forum here) and post in there. The 16-bit forum (here) won't help with Windows questions and your posts will be moved.

Cheers,

Zooba :U

* some style constants are combinations of other constants, so they may have more than one bit set. However, each bit still represents one style.
** two DWORDs actually, since there is both a dwStyle parameter and dwStyleEx parameter. This is because more than 32 flags were required.

MichaelW

Here is an example the uses AND and TEST.

Assume that AL contains an ASCII character, and that we need to perform one action if the character is upper case, and another if the character is lower case. For ASCII characters the case of the character is determined by bit 5 of the character code. If bit 5 is set then the character is lower case, and if bit 5 is clear then the character is upper case. For example:

"a" = 97 =  01100001
"A" = 65 =  01000001
bit numbers:76543210

Assume that we determine the state of bit 5 by ANDing AL with 00100000b. For AL = "Z" = 90 = 01011010 the result is zero, so the zero flag is set:

AL          = 01011010
mask        = 00100000
AL AND mask = 00000000

For AL = "z" = 122 = 01111010 the result is 00100000b (non zero), so the zero flag is cleared:

AL          = 01111010
mask        = 00100000
AL AND mask = 00000000

We can then use a JZ conditional jump (Jump if Zero flag is set) to jump to the code that performs the upper case action when the character is upper case, or "fall through" to the code that performs the lower case action when the character is lower case.

; AL = character
AND AL, 00100000b
; AL = 00000000 or 00100000
JZ  performUpperCaseAction
; perform lower case action here
...
performUpperCaseAction:
...

The code above will perform the correct action based on the case of the character, but because AND stores the result in the destination operand (AL in this case), the character will be overwritten. If the code that performs the action needs the character, then it must reload the character. This problem can be corrected by using TEST instead of AND. Test works just like AND, setting the flags just as AND would, but the result is not stored in the destination operand, so the character in AL is not disturbed.

; AL = character
TEST AL, 00100000b
; AL = character
JZ  performUpperCaseAction
; perform lower case action here
...
performUpperCaseAction:
...
eschew obfuscation

AssemblyBeginner

thks once again MichacelW and zooba clearing my many doubts reagarding AND,OR,XOR and Test.


hi zooba i don;t understand this one,where it returns 1 isf bit macth and zero is none


as TEST is AND but not store result
in this AND 11010001b,00010000b = 00010000b and zf=0
and jnz BitWasSet condition satisfies and jump goes to BitWasSet
but i don't understand about return value 1 and 0
plz clear my doubt regarding this and


TEST can also be interpreted as a bit-test. You pass it two values and it returns 1 if any of the 1 bits match and zero if none of them match.

Code:
mov  al, 11010001b
test al,00010000b
jnz  BitWasSet
jz   BitWasNotSet

In this way, it is possible to use a 32-bit value to represent 32 boolean values (on/off, or true/false). If a bit is set, it is true. If a bit is clear, it is false



and plz expalin this one also with other way

The internal Windows code will use TEST to see which styles you want and base its actions on those. This way, any combination of the flags is possible.

Since 1 is accepted to be true, ORing styles together indicates that each of those styles is desired. If a style is not ORed into the style value, its respective bit won't be set, using TEST will return 0 and the style won't be used.