Основные арифметические команды
ADD – целочисленное сложение
! запрещено в качестве обоих операндов использовать две ячейки памяти
ADC – сложение с переносом (как правило используется для 32-х разрядных чисел)
Складывает 1 и 2 операнд и прибавляет значение флага CF, при этом 1-й операнд теряется
Пример для 5FFFFh и 20005h
numl dw 0FFFFh ; младшая часть
numh dw 0005h ; старшая часть
.............
mov AX,0005h ; младшая часть
mov BX,0002h ; старшая часть
add ax,numl ; AX = 4, CF = 1
adc bx,numh ; BX:AX=0008:0004=80004h
SUB – вычитание целых чисел
SBB – целочисленное вычитание с заемом
Пример для 20000h-1000Ah:
num1 dw Ah
num2 dw 1h
mov ax,0
mov dx,2
sub ax,num1
sbb dx,num2
IMUL – умножение целых знаковых чисел
Умножение на AL или AX, при умножении на AX результат сохраняется в DX:AX, на AL – в AX
Недопустимо умножение на непосредственное число
Пример:
MOV AL,5
MOV BL,3
IMUL BL ; AX=000Fh
MOV AL,-5
MOV BL,3
IMUL BL ; AX = FFF1h
MUL – умножение знаковых чисел
Пример:
MOV AX, 256
MOV BX, 256
MUL BX ; DX = 0001h AX = 0000h (65536)
IDIV – деление знаковых
В команде указывается делитель
1) В аккумуляторе AX – результат в AL (частное), AH – остаток
2) В DX – старшая часть числа, в AX – младшая, результат в AX, остаток – в DX
Пример:
MOV AX, -506
MOV BL, 50
IDIV BL ; AL = F6h(-10) AH = FAh (-6)
DIV – деление беззнаковых
MOV DX,1
MOV AX,1
MOV CX,256
DIV CX ; AX = 0100h
CBW – преобразует байт в слово (60h из AL в 0060h в AX, передавая знаковый бит через AH)
CBW ; расширение AL до AX
ADD AX, 20h ; прибавить к AX
Многословное сложение
WORD1A DW 0123h ; первое число старшая часть
WORD1B DW BC62h ; второе число старшая часть
WORD2A DW 0012h ; первое число младшая часть
WORD2B DW 553Ah ; второе число младшая часть
WORD3A DW ?
WORD 3B DW ?
;--------------------------------------
MAIN PROC NEAR ; основная процедура
CALL DWD1 ; вызвать сложение 1
CALL DWD2 ; вызвать сложение 2
RET
MAIN ENDP
;--------------------------------------
DWD1 PROC ; работает не в общем случае
MOV AX, WORD1B ; сложить правые слова
ADD AX, WORD2B
MOV WORD3B, AX
MOV AX, WORD1A ; сложить левые слова
ADC AX, WORD2A ; с переносом
MOV WORD3A, AX
RET
DWD1 ENDP
;------------------------------------
DWD2 PROC ; сложение любой длины
CLC ; очистить флаг переноса
MOV CX,2 ; счетчик
LEA SI, WORD1B ; левое слово первого
LEA DI, WORD2B ; левое слово второго
LEA BX, WORD3B ; левое слово суммы
E20:
MOV AX,[SI] ; поместить слово в AX
ADC AX, [DI] ; сложить с переносом
MOV [BX], AX ; сохранить слово
DEC SI
DEC SI
DEC DI
DEC DI
DEC BX
DEC BX
LOOP E20
RET
DWD2 ENDP
Ascii-формат
Команды для арифметических операций:
AAA – коррекция для сложения
Пример:
MOV AX, 0605h ; двоично-десятичное 605
ADD AL, 09h ; двоично-десятичное 09 в AX = 060Eh
AAA ; AX = 0704 т.е. двоично-десятичное 74
AAD – коррекция для деления
Пример:
MOV AX, 0207h ; 27 десятичное
MOV DL, 06h
AAD ; AX = 001B=27 десятичное
DIV DL ; AX = 0304
AAM – коррекция для умножения
Пример:
MOV AL, 08h ; 8 десятичное
MOV CL, 07h ; 7 десятичное
MUL CL ; AX = 0038h = 56 десятичное
AAM ; AX = 0506h
AAS – коррекция для вычитания
Пример:
MOV AX, 0708h ; 78 десятичное
MOV CL, 09h ; 9 десятичное
SUB AL, CL ; AX = 07FF (CF = 1)
AAS ; AX = 0609h
TITLE EXCONV (COM)
CODESG SEGMENT PARA ‘CODE’
ASSUME CS:CODESG, DS:CODESG, SS:CODESG
ORG 100h
BEGIN: JMP SHORT MAIN
ASCVAL DB ‘1234’
BINVAL DB 0
ASCLEN DB 4
MULT10 DB 1
; ----------------------------------------
MAIN PROC NEAR ; основная процедура
CALL B10ASBI
CALL C10BIAS
RET
MAIN ENDP
; ---------------------------------------- преобразование в двоичное
B10ASBI PROC
MOV CX, 10 ; фактор умножения
LEA SL, ASCVAL-1 ; адрес ASCVAL
MOV BX, ASCLEN ; длина ASCVAL
B20:
MOV AL, [SI+BX] ; выбрать ASCII-символ
AND AX, 000Fh ; очистить зону тройки (31 -> 1; 34 -> 4 etc.)
MUL MULT10 ; умножить на фактор 10
ADD BINVAL ; прибавить к двоичному
MOV AX, MULT10 ; вычислить следующий
MUL CX ; фактор умножения
MOV MULT10, AX
DEC BX ; последний ASCII-символ ?
JNZ B20 ; нет – продолжить
RET
B10ASBI ENDP
; ----------------------------------------
