CIS-77 Home http://www.c-jump.com/CIS77/CIS77syllabus.htm
The ADD, INC (Increment), SUB, and DEC (Decrement) instructions have two requirements:
If there are two operands, only one operand can be a memory operand.
If there are two operands, both must be the same size. For example,
add ebx, eax ; Add two registers, result stored in EBX add eax, [ebx] ; Add register and a doubleword in memory add [value], 10h ; Add immediate value to a doubleword
Processor status is described as condition codes, or status flags.
Condition codes refer to the information about most recently executed instruction.
For example, if decrementing a register produces zero value, the zero flag ZF is set by the processor.
(A programmer might say: zero condition has occurred.)
Each flag is a single bit in the flag register, EFLAGS.
If last addition or subtraction produced a negative result, the sign flag SF is set.
Sign flag SF is equal to the high-order bit of the result of an operation:
0 is positive,
1 is negative.
When numbers are added and subtracted, carry flag CF represents
9th bit, if 8-bit numbers added
17th bit, if 16-bit numbers added
33rd bit, if 32-bit numbers added
and so on.
With addition, the carry flag CF records a carry out of the high order bit. For example,
mov al, -1 add al, 1 ; AL = 0, ZF and CF flags are set to 1
When a larger number is subtracted from the smaller one, the carry flag CF indicates a borrow. For example,
mov al, 6 sub al, 9 ; AL = -3, SF and CF flags are set to 1
The result is -3, represented internally as 0FDh (binary 11111101).
Arithmetic operations have a potential to run into a condition known as overflow.
Overflow occurs with respect to the size of the data type that must accommodate the result.
Overflow indicates that the result was
too large, if positive, or
too small, if negative,
to fit in the original data type.
When two signed 2's complement numbers are added, the overflow flag OF indicates one of the following:
both operands are positive and the result is negative, or
both operands are negative and the result is positive.
When two unsigned numbers are added, the carry flag CF indicates an overflow, that is,
there is a carry out of the leftmost (most significant) bit.
Computers don't know the difference between signed and unsigned binary numbers.
This is a good thing, because it makes logic circuits fast.
This is also a bad thing, because distinguishing between signed and unsigned becomes programmer's responsibility.
Distinction between signed and unsigned data types is very important when detecting an overflow after addition or subtraction.
Correct approach to detect the overflow is to consider two separate cases:
Overflow when adding signed numbers is indicated by the overflow flag, OF.
Overflow when adding unsigned numbers is indicated by the carry flag, CF.
The INC instruction adds one to the destination operand,
while preserving the state of the carry flag CF:
The destination operand can be a register or a memory location.
This instruction allows a loop counter to be updated without disturbing the CF flag.
(Use ADD instruction with an immediate operand of 1 to perform an increment operation that does update the CF flag.)
The DEC instruction subtracts one from the destination operand,
while preserving the state of the CF flag.
(To perform a decrement operation that does update the CF flag, use a SUB instruction with an immediate operand of 1.)
Especially useful for incrementing and decrementing counters.
A register is the best place to keep a counter.
The INC and DEC instructions
always treat integers as unsigned values
never update the carry flag CF, which would otherwise (i.e. ADD and SUB) be updated for carries and borrows.
The instructions affect the OF, SF, ZF, AF, and PF flags just like addition and subtraction of one.
xor al, al ; Sets AL = 0. XOR instruction always clears OF and CF flags. mov bl, 0FEh inc bl ; 0FFh SF = 1, CF flag not affected. inc bl ; 000h SF = 0, ZF = 1, CF flag not affected.
The following instructions allow direct carry flag manipulation:
CLC clears Carry Flag, CF = 0
STC sets Carry Flag, CF = 1
CMC complements Carry Flag, CF = NOT( CF ).
Examples of 8-bit signed and unsigned addition and subtraction:
.DATA mem8 BYTE 39 ; 0010 0111 27 ; .CODE ; Addition + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ; signed unsigned binary hex mov al, 26 ; Start with register 26 26 0001 1010 1A inc al ; Increment +1 +1 ; ---- ---- ; 27 27 0001 1011 1B add al, 76 ; Add immediate +76 +76 0100 1100 4C ; ---- ---- ; 103 103 0110 0111 67 add al, [mem8] ; Add memory +39 +39 0010 0111 27 ; ---- ---- mov ah, al ; Copy to AH -114 142 1000 1110 8E (OF) (SF) add al, ah ; Add register + -114 +142 1000 1110 8E ; ---- ---- ; 28 28 0001 1100 1C (OF) (CF) ; Subtraction- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; signed unsigned binary hex mov al, 95 ; Load register 95 95 0101 1111 5F dec al ; Decrement - 1 - 1 ; ---- ---- ; 94 94 0101 1110 5E sub al, 23 ; Subtract immediate - 23 - 23 1110 1001 E9 ; ---- ---- ; 71 71 0100 0111 47 mov [mem8],122 ; Load memory sub al, [mem8] ; Subtract memory - 122 - 122 0111 1010 7A ; ---- ---- ; -51 205 1100 1101 CD (SF) (CF):borrow mov ah, 119 ; Load register sub al, ah ; and subtract - 119 - 119 0111 0111 77 ; ---- ---- ; 86 86 0101 0110 56 (OF)
(OF) overflow flag indicates that result is too large to fit in the 8-bit destination operand:
the sum of two positive signed operands exceeds 127.
the difference of two negative operands is less than -128.
(CF) carry flag indicates that the sum of two unsigned operands exceeded 255.
(SF) sign flag indicates that result goes below 0.
To verify the above conditions, try ADD_SUB_EFLAGS.exe demo program ADD_SUB_EFLAGS.ASM ( download source here.)
LAHF instruction loads lower byte of the EFLAGS register into AH register.
The lowest 8 bits of the flags are transferred:
Sign
Zero
Auxiliary Carry
Parity
Carry
Instruction format:
lahf
SAHF restores the value of lower byte flags. Format:
sahf
The NEG instruction negates a value by finding 2's complement of its single operand.
This simply means multiply operand by -1.
When a positive value is negated the result is negative.
A negative value will become positive.
Zero remains zero.
For example,
mov al, -1 ; Load register neg al ; AL now has 1
|
|
SHL is very useful for computing powers of 2 and multiplication by 2, since each time binary number is shifted left, its numeric value doubles.
SHR does the opposite of SHL.
Zeroes are shifted in from the left, right bits moved to CF.
Operation of SHR:
|
|