LOGICAL INSTRUCTIONS
Comparing Data
The compare instruction works the same as the subtract instruction except
that the resulting data variables are thrown away. What is important about the
compare instruction is that the Flag register is reset by the operation. This
allows for conditional branching following the compare instruction. There are 8
bit and 16 bit compares.
Example:
;compare AX to data (AX-data)
cmp ax,data
;compare data to AX (data-AX)
cmp data,ax
;compare AX to 11 (AX-11)
cmp ax,11
;compare data to 11 (data-11)
cmp data,11
Note that you can compare a sign extended immediate
8 bit data value to a 16 bit data value.
Example:
cmp ax,1
String
Instructions
String instructions can be used with the repeat command. When using the
repeat command (REP), you must always preset the direction flag and register CX
with the count. There are five standard string commands that can work in either
byte mode or word mode. The five commands are MOVS, CMPS, SCAS, LODS, and STOS.
The move string (MOVS) is explained in the appendix on moving data. The string
compare (CMPS) is used to compare two different strings of data in memory to
each other. To use the string compare instructions, you must set DS:SI to index
source memory location and ES:DI to index destination memory location. After
each byte or word compare with a string instruction, the SI and DI registers
are altered to index the next location. If a repeat command is used with a
string instruction, the CX register is decremented by one and then tested for
zero to determine if the loop should continue. There is an instruction to
compare the contents of memory to the accumulator (SCAS). The LODS is used to
load the accumulator with a string of data values from memory. The STOS is used
to store the contents of the accumulator to a string of memory.
Examples:
; define string locations for comparing
string1 db ’test string ’,0
string2 db ’test string ’,0
string_size equ 12
;get ready for string compare
cld ;go forward
mov cx,string_size
lea si,string1
lea di,string2
;test to see if two strings are equal
repe cmpsb
;branch if strings donot match
jne strings_donot_match
strings_donot_match:
;find end of ASCIIZ string
cld ;search forward
mov cx,200 ;set to max string size
;set accumulator to zero for end of string character
mov al,0
lea di,string2
;repeat search until zero found or CX = 0
repne scasb
;branch if no end of string found
jne no_end_of_string
no_end_of_string:
;set block of memory to zero
cld ;go forward
mov cx,6 ;size of block in words
lea di,string1
mov ax,0
;write zeros to block
rep stosw
Bit Manipulating
Instructions
These instructions are used to deal with data one bit at a time. They are
used in many graphics routines for controlling the bit patterns of video
arrays. The basic instructions are the logical Boolean operations.
;AND accumulator with 0000 0000 0000 1111 bit pattern
AND ax,0FH
;OR memory data with bit pattern in accumulator
OR data,ax
;eXclusive OR accumulator with bit pattern in register DX
XOR ax,dx
;reverse bit pattern in accumulator
NOT ax
Testing Data
The TEST instruction is the same as the AND instruction but the result only
affects the Flag register without affecting any of the operand data values.
Example:
test al,80H ;Test high bit
Bit Shifting
Instructions
The basic logical and arithmetic shift instructions have the same effect as
multiplying or dividing a number. If you take a binary number and shift all the
bits over one position right, this is the equivalent of multiplying by 0.5 or
dividing by 2, which is the same as cutting the value of a binary number in
half.
SHR
logical shift right, move zero into
high bit position and move low bit into carry flag.
SHL
logical shift left, move zero into
low bit position and move high bit into carry flag.
SAR
arithmetic shift right, keep same
value in the high bit position and move low bit into carry flag.
SAL
arithmetic shift left, move zero
into low bit position and move high bit into carry flag.
ROL
rotate left, move high bit position
to low bit position.
ROR
rotate right, move low bit position
to high bit position.
RCL
rotate left through carry flag, move
high bit data to carry flag and move carry flag data to low bit position.
RCR
rotate right through carry flag,
move low bit data to carry flag and move carry flag data to high bit position.
No Operation
When debugging code at the Assembly language level, you will probably
encounter NOP instructions inserted into the executing code. The NOP
instruction is used for many reasons. Most of these reasons have to do with
compiler problems. In complex instruction sets, there are variable length
instructions. These instructions create problems for compilers that must
allocate space for the instruction without knowing the exact size of the final
instruction. For example, there are near CALLs and far CALLs. When the compiler
runs into a subroutine CALL, it may not know if it is a near CALL or a far
CALL. The near CALL instruction will only need three bytes and the far CALL
instruction will need five bytes. The compiler must assume worst case and
assign space for the far CALL even though it may be a near CALL. If it turns
out to be a near CALL, then there is the problem of what to do with the space
not used. A solution is to insert NOP instructions into the unused spaces. This
is one reason why all computers with complex instruction sets have a no
operation instruction.