1. ADD
2. ADC
3. INC
Этим командам безразлично знаковые числа или нет. Если в результате сложения результат не помещается в отведенном месте флаг переноса принимает значение CF=1.
Состояние флагов после выполнения команд ADD,ADC,INC
Флаги | Пояснения |
CF=1 | Результат не поместился в приемнике |
PF=1 | Результат имеет четное количество единиц |
SF=1 | Копируется старший разряд результата |
ZF=1 | Результат выполнения команд =0 |
OF=1 | Если результат сложения 2 чисел одного знака получился больше допустимого значения. В этом случае приемник меняет знак |
Команда сложения ADD
add приемник,источник
<Приемник>=<Приемник>+<Источник>
Сочетания операндов как в команде MOV
ADC -> ADdition with Carry
Использует бит переноса. Может использоваться для сложения 32х разрядных чисел.
ADC приемник,источник
<Приемник>=<Приемник>+<Источник>+<CF>
Обычно используется в паре с ADD
ПРИМЕР
;x=a+b
.DATA
Extrn x:Dword,a:Dword,b:Dword
.CODE
Public addal
addal proc far
mov ax,word PTR a;В регистр ах помещается младшая часть а
mov bx,word PTR a+2;В регистре bx пощается старшая часть a
|
|
mov cx,word PTR b
mov dx,wors PTR b+2
add ax,cx;<ax>=<ax>+<cx>
adc bx,dx;<bx>=<bx>+<dx>+<CF>
mov word PTR x,ax
mov word PTR x+2,bx
ret
addal endp
...
end
INC->Increment operand by 1
Увеличивает значение операнда на единицу
INC операнд
<операнд>=<операнд>+1
В качестве операнда может быть регист или память
Команды вычитания
· SUB->substract
· SBB->substract with borrow CF
· DEC->Decrement
· NEG->Negative operand(Регистры,память)
<AL>=50-<AL>
ВАРИАНТ 1
mov BL,50
sub BL,AL
mov AL,BL
ВАРИАНТ 2
NEG AL
ADD AL,50
· CMP->
Первые 3 команды обратны командам ADD,ADC,INC
ЛЕКЦИЯ 7
........
Пример:
Вычислить z=5*w для без знаковых 16разрядных чисел
.data
Extrn w:word, z:word
.code
Public mulword
Mulword proc far
mov cx,5
mov ax,w
mul cx
mov word PTR z,ax
mov word PTR z+2,dx
ret
Mulword endp
КОМАНДЫ ДЕЛЕНИЯ
DIV ->Без знаковое деление
IDIV ->знаковое
DIV источник
IDIV источник
Команды деления источник - 95% ошибок для нубов а ассемблере
Логика работы
<частное:остаток>=<Делимое>/<Делитель-источник>
Делитель - регистр или память, константы не допускаются
Делимое и частное с остатком являются не явными операндами, они находятся в строго определенном месте в зависимости от длины делителя.
РЕЗУЛЬТАТ | РЕЗУЛЬТАТ | ||
Длина делителя | Делимое | Частное | остатком |
BYTE | AX | AL | AH |
WORD | <DX:AX> | AX | DX |
Результат состоит из частного и остатка. Длина делимого всегда в 2 раза больше чем делителя. Команды деления также вырабатывают флаги и всегда генерируют прерывание которое называется деление на 0.
Пример
Z=(5*W)/4
Воспользуемся предыдущим примером (умножением) имея в виду что произведение хранится в 2х регистрах DX и AX.
.DATA
Extrn w:word,z:word
.code
Public Divword
|
|
Divword proc far
mov cx,5
mov ax,w
mul cx;<DX:AX>
mov cx,4;Делитель-><CX>
div cx;5+w/4-><ax>
mov z,ax
ret
Divword endp
КОМАНДЫ РАСПРОСТРАНЕНИЯ ЗНАКА
CBW, CWD
Работу этих команд рассмотрим на примере
z=w/10 16разрядные беззнаковые
.data
Extrn z:word,w:word
.code
Public divA
divA proc far
mov ax,w
mov cx,10
div cx;результат в <ax>
mov z,ax
ret
divA endp
Если запустить эту подпрограмму из СРР модуля получим неверный результат. Причина в том что в этой процедуре делимое не подготовлено к делению.
Как подготовить делимое к делению?
В предыдущем примере подготовку делимого сделала команда умножения. В этом примере подготовку необходимо сделать самому.
1. При делении без знаковых чисел в старшую часть делимого нужно занести 0. Командой mov занести в регистр dx 0 (не эффективно)
2. XOR - команда деления по модулю. xor dx,dx-> <dx> = 0
При делении знаковых чисел используются команды распространения знака.
CBW->Convert Byte to Word-> <AL> -> <AX> (AL занимает весь AX)
CWD->Convert Word to Double-> <AX> -> <DX:AX>
Эти команды также используются для выравнивания операндов по длине
Логика работы команды CBW
Содерж. Старшой част. <Ah> | Извесна младшая часть<AL> | |
Биты 15-8 | Бит 7 | Биты 6-0 |
1111 1111 | Инф.часть | |
0000 0000 | Инф.часть |
Логика работы команды CWD
Содерж. Старшой част. <DX> | Извесна младшая часть<AX> | |
Биты 16-31 | Бит 15 | Биты 14-0 |
1111 1111 1111 1111 | Инф.часть | |
0000 0000 0000 0000 | Инф.часть |
Если применить команды CWD и CBW получим деление на 0.
Примеры:
Z=W/10
Беззнаковое деление типа WORD
mov ax,w;делимое w-> <AX>
mov cx,10:делитель-> <cx>
XOR dx,dx;0-> <dx>
div cx;<ax>=<DX:AX>/<CX>
mov z,ax
Знаковое деление типа word
mov ax,w;делимое w-> <AX>
mov cx,10;делитель-> <cx>
CWD;увеличение длины делимого
idiv cx;<ax>=<DX:AX>/<CX>
mov z,ax
Без знаковое деление типа byte
mov al,w
mov cl,10
XOR ah,ah
div cl
mov z,al
Знаковое деление типа byte
mov al,w
mov cl,10
CBW
idiv cl
mov z,al