home *** CD-ROM | disk | FTP | other *** search
-
-
-
- 47
-
- CHAPTER 7 - LOGIC
-
-
- There are a number of operations which work on individual bits of
- a byte or word. Before we start working on them, it is necessary
- for you to learn the Intel method of numbering bits. Intel starts
- with the low order bit, which is #0, and numbers to the left. If
- you look at a byte:
-
- 7 6 5 4 3 2 1 0
-
- that will be the ordering. If you look at a word:
-
- 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
-
- that is the ordering. The overwhelming advantage of this is that
- if you extend a number, the numbering system stays the same. That
- means that if you take the number 45 :
-
- 7 6 5 4 3 2 1 0
- 0 0 1 0 1 1 0 1 (45d)
-
- and sign extend it:
-
- 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1
-
- each of the bits keeps its previous numbering. The same is true
- for negative numbers. Here's -73:
-
- 7 6 5 4 3 2 1 0
- 1 0 1 1 0 1 1 1 (-73d)
-
- 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 (-73d)
-
- In addition, the bit-position number denotes the power of 2 that
- it represents. Bit 7 = 2 ** 7 = 128, bit 5 = 2 ** 5 = 32,
- bit 0 = 2 ** 0 = 1. {1}.
-
- Whenever a bit is mentioned by number, e.g. bit 5, this is what
- is being talked about.
-
-
- AND
-
- We will use AND as the prototype. There are five different ways
- you can AND two numbers:
-
-
- ____________________
-
- 1 I'm using the Fortran convention for showing exponents. That
- is, 2 ** 7 is 2 to the 7th, 3 ** 19 is 3 to the 19th.
-
- ______________________
-
- The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson
-
-
-
-
- The PC Assembler Tutor 48
- ______________________
-
- 1. AND two register
- 2. AND a register with a variable
- 3 AND a variable with a register
- 4. AND a register with a constant
- 5. AND a variable with a constant
-
- That is:
-
- variable1 db ?
- variable2 dw ?
-
- and cl, dh
- and al, variable1
- and variable2, si
- and dl, 0C2h
- and variable1, 01001011b
-
- You will notice that this time the constants are expressed in hex
- and binary. These are the only two reasonable alternatives. These
- instructions work bit by bit, and hex and binary are the only two
- ways of displaying a number bitwise (bit by bit). Of course, with
- hex you must still convert a hex digit into four binary digits.
-
- The table of bitwise actions for AND is:
-
- 1 1 -> 1
- 1 0 -> 0
- 0 1 -> 0
- 0 0 -> 0
-
- That is, a bit in the result will be set if and only if that bit
- is set in both the source and the destination. What is this used
- for? Several things. First, if you AND a register with itself,
- you can check for zero.
-
- and cx, cx
-
- If any bit is set, then there will be a bit set in the result and
- the zero flag will be cleared. If no bit is set, there will be no
- bit set in the result, and the zero flag will be set. No bit will
- be altered, and CX will be unchanged. This is the standard way of
- checking for zero. You can't AND a variable that way:
-
- and variable1, variable1
-
- is an illegal instruction. But you can AND it with a constant
- with all the bits set:
-
- and variable1, 11111111b
-
- If the bit is set in variable1, then it will be set in the
- result. If it is not set in variable1, then it won't be set in
- the result. This also sets the zero flag without changing the
- variable.
-
- AND is also used in masks, which will be covered at the end of
- the chapter.
-
-
-
-
- Chapter 7 - Logic 49
- _________________
-
-
- Finally, there is a variant of AND called TEST. TEST does exactly
- the same thing as AND but throws away the results when it is
- done. It does not change the destination. This means that it can
- check for specific things without altering the data. It has the
- same possibilities as AND:
-
- variable1 db ?
- variable2 dw ?
-
- test cl, dh
- test al, variable1
- test variable2, si
- test dl, 0C2h
- test variable1, 01001011b
-
- will set the flags exactly the same as the similar AND
- instructions but will not change the destination. We need a
- concrete example, and for that we'll turn to your video card. In
- text mode, your screen is 80 X 25. That is 2000 cells. Each cell
- has a character byte and an attribute byte. The character byte
- has the actual ascii number of the character. The attribute byte
- says what color the character is, what color the background is,
- whether the character is high or low intensity and whether it
- blinks. An attribute byte looks like this:
-
- 7 6 5 4 3 2 1 0
- X R G B I R G B
-
- Bits 0,1 and 2 are the foreground (character) color. 0 is blue, 1
- is green, and 2 is red. Bits 4, 5, and 6 are the background
- color. 4 is blue, 5 is green, and 6 is red. Bit 3 is high
- intensity, and bit 7 is blinking. If the bit is set (1) that
- particular component is activated, if the bit is cleared (0),
- that component is deactivated.
-
- The first thing to notice is how much memory we have saved by
- putting all this information together. It would have been
- possible to use a byte for each one of these characteristics, but
- that would have required 8 X 2000 bytes = 16000 bytes. If you add
- the 2000 bytes for the characters themselves, that would be 18000
- bytes. As it is, we get away with 4000 bytes, a savings of over
- 75%. Since there are four different screens (pages) on a color
- card, that is 18000 X 4 = 72000 bytes compared to 4000 X 4 =
- 16000. That is a huge savings.
-
- We don't have the tools to access these bytes yet, but let's
- pretend that we have moved an attribute byte into dl. We can find
- out if any particular bit is set. TEST dl with a specific bit
- pattern. If the zero flag is cleared, the result is not zero so
- the bit was on. If the zero flag is set, the result is zero so
- that bit was off
-
-
- test dl, 10000000b ; is it blinking?
- test dl, 00010000b ; is there blue in the background?
- test dl, 00000100b ; is there red in the foreground?
-
-
-
-
- The PC Assembler Tutor 50
- ______________________
-
-
- If we look at the zero flag, this will tell us if that component
- is on. It won't tell us if the background is blue, because maybe
- the green or the red is on too. Remember, test alters neither the
- source nor the destination. Its purpose is to set the flags, and
- the results go into the Great Bit Bucket in the Sky.
-
-
- OR
-
- The table for OR is:
-
- 1 1 -> 1
- 1 0 -> 1
- 0 1 -> 1
- 0 0 -> 0
-
- If either the source or the destination bit is set, then the
- result bit is set. If both are zero then the result is zero.
- OR is used to turn on a specific bit.
-
- or dl, 10000000b ; turn on blinking
- or dl, 00000001b ; turn on blue foreground
-
- After this operation, those bits will be on whether or not they
- were on before. It changes none of the bits where there is a 0.
- They stay the same as before.
-
-
- XOR
-
- The table for XOR is:
-
- 1 1 -> 0
- 1 0 -> 1
- 0 1 -> 1
- 0 0 -> 0
-
- That is, if both are on or if both are off, then the result is
- zero. If only one bit is on, then the result is 1. This is used
- to toggle a bit off and on.
-
- xor dl, 10000000b ; toggle blinking
- xor dl, 00000001b ; toggle blue foreground
-
- Where there is a 1, it will reverse the setting. Where there is a
- 0, the setting will stay the same. This leads to one of the
- favorite pieces of code for programmers.
-
- xor ax, ax
-
- zeros the ax register. There are three ways to zero the ax
- register:
-
- mov ax, 0
- sub ax, ax
- xor ax, ax
-
-
-
-
- Chapter 7 - Logic 51
- _________________
-
-
- The first one is very clear, but slightly slower. For the second
- one, if you subtract a number from itself, you always get zero.
- This is slightly faster and fairly clear.{2} For the third one,
- any bit that is 1 will become 0, and and bit that is 0 will stay
- 0. It zeros the register as a side effect of the XOR instruction.
- You'll never guess which one many programmers prefer. That's
- right, XOR. Many programmers prefer the third because it helps
- make the code more obsure and unreadable. That gives a certain
- aura of technical complexity to the code.
-
-
-
- NEG and NOT
-
- NOT is a logical operation and NEG is an arithmetical operation.
- We'll do both here so you can see the difference. NOT toggles the
- value of each individual bit:
-
- 1 -> 0
- 0 -> 1
-
- NEG negates the value of the register or variable (a signed
- operation). NEG performs (0 - number) so:
-
- neg ax
- neg variable1
-
- are equivalent to (0 - AX) and (0 - variable1) respectively. NEG
- sets the flags in the same way as (0 - number).
-
- ; negvsnot.asm
- ; compares the operations NEG and NOT
- ; + + + + + + + + + + + + + + + START CODE BELOW THIS LINE
- mov ax_byte, 1 ; signed
- mov bx_byte, 1 ; signed
- mov cx_byte, 1 ; signed
- mov si_byte, 3 ; binary
- mov di_byte, 3 ; binary
- mov bp_byte, 3 ; binary
- mov dx, 0 ; not used, so clear
- lea ax, ax_byte
- call set_reg_style
- call show_regs
-
- outer_loop:
- call get_signed ; get number
- mov bx, ax ; move it to all registers
- mov cx, ax
- mov si, ax
- mov di, ax
- mov bp, ax
-
- not bx ; NOT the second row down
- ____________________
-
- 2 This is one of the first instructions in the template files.
-
-
-
-
- The PC Assembler Tutor 52
- ______________________
-
- not di
- neg cx ; NEG the third row down
- neg bp
-
- call show_regs
- jmp outer_loop
-
- ; + + + + + + + + + + + + + + + END CODE ABOVE THIS LINE
-
-
- This is set up so the left registers are signed and the right
- registers are binary. The top registers retain the original
- value, the second registers down will do NOT and the third
- registers down will do NEG.
-
- Put a number in. On the right side, you will see that NOT (in DI)
- reverses the bit pattern, while on the left, NEG (in CX) negates
- the number. Do a few more. This is always true. But they seem to
- be related. In fact, BX will always be 1 too negative. Why?
- Remember that in the introduction on numbers, when we changed
- signs, we had:
-
- negative of number = one's complement + 1
-
- but the one's complement is exactly NEG. It switches the value of
- each bit. To get the values in the third row (CX and BP), simply
- add 1 to the values in the second row (BX and DI). Remember, NOT
- is a logical operation, NEG is an arithmetic operation.
-
-
- MASKS
-
- To explain masks, we'll need some data, and we'll use the
- attribute byte for the monitor. Here it is again:
-
- 7 6 5 4 3 2 1 0
- X R G B I R G B
-
- Bits 0,1 and 2 are the foreground (character) color. 0 is blue, 1
- is green, and 2 is red. Bits 4, 5, and 6 are the background
- color. 4 is blue, 5 is green, and 6 is red. Bit 3 is high
- intensity, and bit 7 is blinking.
-
- What we want to do is turn certain bits on and off without
- affecting other bits. What if we want to make the background
- black without changing anything else? We use and AND mask.
-
- and video_byte, 10001111b
-
- Bits 0, 1, 2, 3 and 7 will remain unchanged, while bits 4, 5 and
- 6 will be zeroed. This will make the background black. What if we
- wanted to make the background blue? This is a two step process.
- First we make the background black, then set the blue background
- bit. This involves first the AND mask, then an OR mask.
-
- and video_byte, 10001111b
- or video_byte, 00010000b
-
-
-
-
- Chapter 7 - Logic 53
- _________________
-
-
- The first instruction shuts off certain bits without changing
- others. The second turns on certain bits without effecting
- others. The binary constant that we are using is called a mask.
- You may write this constant as a binary or a hex number. You
- should never write it as a signed or unsigned number (unless you
- are one of those people who just adores making code unreadable).
-
- If you want to turn off certain bits in a piece of data, use an
- AND mask. The bits that you want left alone should be set to 1,
- the bits that you want zeroed should be set to 0. Then AND the
- mask with the data.
-
- If you want to turn on certain bits in a piece of data, use an OR
- mask. The bits that you want left alone should be set to 0. The
- bits that you want turned on should be set to 1. Then OR the mask
- with the data.
-
- Go back to AND and OR to make sure you believe that this is what
- will happen.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The PC Assembler Tutor 54
- ______________________
-
- SUMMARY
-
-
- For AND, TEST, OR, and XOR you can have the following
- combinations:
-
- 1. two register
- 2. a register with a variable
- 3 a variable with a register
- 4. a register with a constant
- 5. a variable with a constant
-
-
- AND is a bitwise logical operation.
-
- 1 1 -> 1
- 1 0 -> 0
- 0 1 -> 0
- 0 0 -> 0
-
- TEST does the same thing as AND except that the result is
- discarded. It is used for setting the flags without altering the
- data.
-
- OR is a bitwise logical operation.
-
- 1 1 -> 1
- 1 0 -> 1
- 0 1 -> 1
- 0 0 -> 0
-
- XOR is a bitwise logical operation.
-
- 1 1 -> 0
- 1 0 -> 1
- 0 1 -> 1
- 0 0 -> 0
-
-
-
- You can use NOT and NEG with either a register or a variable in
- memory.
-
- NOT is a bitwise logical operation
-
- 0 -> 1
- 1 -> 0
-
- NEG is an arithmetic operation. NUMBER -> - NUMBER. It gives the
- negative of a signed number.
-
-
- MASKS
-
- If you want to turn off certain bits of a piece of data, use
- an AND mask. The bits that you want left alone should be set
- to 1, the bits that you want zeroed should be set to 0. Then
-
-
-
-
- Chapter 7 - Logic 55
- _________________
-
- AND the mask with the data.
-
- If you want to turn on certain bits of a piece of data, use
- an OR mask. The bits that you want left alone should be set
- to 0. The bits that you want turned on should be set to 1.
- Then OR the mask with the data.
-
-