Как сложить два числа в Ассемблере
Главная / Ассемблер / Примеры (исходники) /
Как выучить английский
В наше время любой человек должен знать английский язык. А тем более программист. Потому что довольно большая часть документации существует только на английском. А профессионал не может ждать, пока кто-то переведёт ему документацию. Он должен уметь быстро получать нужную инфорамцию и использовать её, независимо от того, на каком она языке — на английском или на русском… Ссылки на курсы по английскому… |
Складывать числа в ассемблере не так уж и сложно. В подавляющем большинстве случаев это делается с помощью команды ADD. Но в любой задаче, даже самой простой, могут встретиться неожиданности, которые не может предусмотреть новичок в силу того, что не имеет достаточного опыта и знаний.
Итак, первое, что нам надо помнить — это размер числа. Если мы складываем два числа, то размер результата может быть больше, чем размер регистра, в который помещается результат.
Второе — мы можем складывать и отрицательные числа. Следовательно, и результат может быть отрицательным.
И да — сложение положительного и отрицательного чисел — это, по сути, вычитание одного числа из другого. Хотя для вычитания в ассемблере есть команда SUB.
Команда ADD существует с незапамятных времён — ещё с процессора 8086. Поэтому она поддерживается и всеми последующими процессорами Интел и совместимыми.
Простейший пример использования:
MOV AL, 3 ADD AL, 2 ; AL = 3 + 2 = 5
Здесь мы сначала записали число 3 в регистр AL, а затем применили команду ADD для сложения числа в AL с числом 2. Результат записывается в нашем случае в AL. И там после выполнения команды будет число 5.
Но складывать можно не только значение в регистре с числом. Но и, например, значения двух регистров:
MOV BX, 7 MOV AX, 2 ADD AX, BX ; AX = 7 + 2 = 9
Также вместо регистров можно использовать память:
MOV [110h], 3 ADD [110h], 2 ; По адресу [110h] теперь хранится 5 MOV AL, 1 ADD AL, [110h] ; AL = 6
При работе с памятью, конечно, надо понимать, что находится по данному адресу и к каким последствиям может привести прямое обращение к памяти и изменение её содержимого. В данном примере на это мы внимания не обращаем. Это просто пример.
Складывать можно не только константы, регистры и память, но и переменные:
ADD BL, MyVar ADD MyVar, 3
Не знаю, во всех ли ассемблерах это будет работать. Но в эмуляторе точно работает. Причём оба варианта. То есть можно записывать результат как в регистр, так и в переменную.
Есть ещё такая тема, как сложение с переносом. Но в этой статье рассматривать её не будет. Больше сведений об этом можно найти здесь.
И есть ещё такая вещь, как BCD-значения. Инструкции для работы с такими значениями: AAA, AAD, AAS, AAM.
На этом пока всё. Подключайтесь к группе Основы программирования в Телеграм, или к другим каналам (ссылки ниже), чтобы ничего не пропустить.
Подписаться на канал в РУТуб
Вступить в группу «Основы программирования» Подписаться на рассылки по программированию |
М. Иванюшин
В одном из предыдущих разделов были опубликованы коды нескольких полезных программ. Но команды, при помощи которых написаны эти программы, оказались скрыты для вас. Здесь мы попробуем показать вам «кухню программирования» и рассмотрим программы сложения, вычитания, умножения, деления, преобразования шестнадцатеричных чисел в десятичные и преобразования десятичных в шестнадцатеричные. Сложение ;СЛОЖЕНИЕ ТРЕХБАЙТНЫХ ЧИСЕЛ ;вход в программу: ;первое слагаемое SL0, SL1, SL2; ;второе слагаемое SL3, SL4, SL5; ;результат работы: ;сумма SL3, SL4, SL5;SUMMA3: LHLD SLO XCHG ;D,E — младшие ;байты первого ;слагаемого LHLD SL3 ;H,L — младшие ;байты второго ;слагаемого DAD D ;H,L — сумма этих ;младших байтов. ;Если при сложении ;возникнет перенос, ;он будет в даль- ;нейшем учтен в ;команде ADC M SHLD SL3 ;сохранили в памяти ;первые два ;байта результата LDA SL2 ;в регистре А ;старший байт ;первого слагаемого LXI H,SL5 ;H,L — адрес ;старшего байта ;второго слагаемого ADC M ;сложение старших ;байтов слагаемых. ;Учтен перенос, ;если он был при ;сложении командой DAD MOV M,A ;результат в SL5 RET Вычитание ;ВЫЧИТАНИЕ ДВУХБАЙТНЫХ ЧИСЕЛ ;вход в программу: ;H,L - уменьшаемое, ;D,E - вычитаемое, ;результат работы: ;В,С - разность.VICh3: MOV A,L ;ВЫЧИТАНИЕ МЛАДШИХ БАЙТОВ SUB E MOV С,А ;ВЫЧИТАНИЕ СТАРШИХ БАЙТОВ MOV А,Н SBB D ;учитывается перенос, ;если он был ;при обработке ;младших байтов MOV В,А RET Для вычисления разности трехбайтных чисел можно использовать следующую программу: ;ВЫЧИТАНИЕ ТРЕХБАЙТНЫХ ЧИСЕЛ ;вход в программу: ;уменьшаемое SL3,SL4,SL5, ;вычитаемое SL0,SL1,SL2, ;результат работы: ;разность SL3,SL4,SL5.VICh4: LXI H,SL0 ;HL — адрес млад- ;шего байта ;вычитаемого LXI D,SL3 ;DE — адрес млад- ;шего байта ;уменьшаемого LDAX D ;A — младший байт ;уменьшаемого SUB М STAX D ;вычислен и сохранен ;младший байт ;разности INX D ;DE — адрес байта SL4 INX H ;HL — адрес байта SL1 LDAX D SBB M STAX D ;в SL4 второй байт ;разности INX H INX D LDAX D SBB M STAX D ;в SL5 третий байт ;разности RET Умножение Микропроцессор КР580ВМ80А не имеет команд умножения, поэтому для выполнения этой математической операции надо составлять программу. Приведенная здесь программа работает по следующему алгоритму: ;УМНОЖЕНИЕ ;вход в программу: ;А - множитель, DE — множимое, ;результат работы: ;HL - произведениеUMNOG: LXI Н,0 ;сброшен промежу- ;точный результат ;****** шаг 3 ****** SHAG3: ORA А ;проверка оконча- ;ния работы RZ ;если содержимое ;регистра А ;равно нулю — ;умножение закончено ;****** шаг 1 ****** RAR ;младший бит мно- ;жителя в переносе INC SDVIG ;если перенос ;равен нулю — ;пропуск сложения DAD D ;сложение множи- ;мого и промежуточ- ;ного результата ;******шаг 2 ****** SDVIG: XCHG DAD H ;сдвиг множимого XCHG JMP SHAG3 В строке с меткой SHAG3 проверка на равенство нулю аккумулятора выполнена при помощи логической операции ИЛИ аккумулятора с самим собой. Эта операция не изменяет содержимое аккумулятора, но устанавливает все признаки. Можно было бы проверить содержимое аккумулятора на равенство нулю при помощи команды CPI 00, но эта команда занимает больше места в памяти и дольше выполняется. Деление ;ДЕЛЕНИЕ ЧЕТЫРЕХБАЙТНОГО ЧИСЛА ;НА ЧЕТЫРЕХБАЙТНОЕ ;вход в программу: ;DE - адрес делимого, ;HL - адрес делителя, ;результат работы: ;RES —частное, ;DE — адрес остатка.DELEN: XRA А STA RES STA RES+1 STA RES+2 STA RES+3 ;сброшено значение ;частного ;ЗАПИСЬ ДЕЛИТЕЛЯ В ЯЧЕЙКУ DEL MOV A,M STA DEL INX H MOV A,M STA DEL+1 INX H MOV A,M STA DEL+2 INX H MOV A,M STA DEL+3 INX H MOV A,M STA DEL+4 LXI H,RES ;вычитание делимого из делителя Rl: LDA DEL MOV C,A LDA DEL+1 MOV B,A LDAX D SBB С STAX D INX D LDAX D SBB В STAX D INX D LDA DEL+2 MOV C,A LDA DEL+3 MOV B,A LDAX D SBB С STAX D INX D LDAX D SBB В STAX D DCX D DCX D DCX D ;восстановлено ;исходное значение ;регистров DE JC KD ;если перенос уста- ;новлен, значит ;делитель стал ;больше делимого PUSH PSW ;запомнено состояние ;переноса ;подсчет числа вычитаний ;делителя из делимого ;HL — адрес результата DELI: INR M JNZ R3 INX H ;если установлен ;признак равенства ;нулю, значит, в ;результате выполнения ; команды INR M ;возник перенос и ;его надо учесть INR М ;увеличен на единицу ;следующий байт ;результата JNZ R2 INX H INR M DCX H ;восстановление ;исходного значения R2: DCX H ;регистров HL R3: POP PSW ;восстановлен ;текущий перенос ;для правильного ;выполнения сложения ;в цикле R1 JMP R1 ;ВОССТАНОВЛЕНИЕ ОСТАТКА KD: LDA DEL MOV C,A LDA DEL+1 MOV B,A LDAX D ADD С STAX D INX D LDAX D ADC В STAX D INX D LDA DEL+2 MOV C,A LDA DEL+3 MOV B,A LDAX D ADC С STAX D INX D LDAX D ADC В STAX D DCX D DCX D DCX D ;DE — адрес остатка RET Преобразование чисел двоичное число: бит7 * 27 + бит6 * 26 + бит5 * 25 + бит4 * 24 + + бит3 * 23 + бит2 * 22 + бит1 * 21 + бит0 * 20 преобразуется к виду: десятичное число: ((((((бит7 * 2 + бит6) * 2 + бит5) * 2 + бит4) * 2 + + бит3) * 2 + бит2) * 2 + бит1) * 2 + бит0. ;ПРЕОБРАЗОВАНИЕ ДВОИЧНОГО ЧИСЛА ;В ДВОИЧНО-ДЕСЯТИЧНОЕ ;BCD2B - программа перевода двухбайтного ;двоичного числа в двоично-десятичное. ;Двоичное число передается ;в регистрах HL, ;результат работы: ;А - десятки тысяч, ;В - тысячи и сотни, ;С - десятки и единицы. ;BCD1B - программа перевода однобайтного ;числа в двоично-десятичный код. ;Двоичное число записывается ;в регистр Н, регистр L сбрасывается. ;результат работы: ;А - разряды сотен, ;В - разряды десятков и единиц. BCD2B: MVI Е,17 ;установка счетчика ;первого цикла CALL CONV ;вычисление младшего ;двоично-десятичного байта MOV С,А ;вычисленный результат сохранен MVI Е,17 ;установка счетчика ;второго цикла JMP PROD BCD1B: MVI E,9 ;установка счетчика ;для программы BCD1B CALL CONV ;вычисление двух ;старших байтов MOV В,А ;запомнен промежуточный ;двоично-десятичный результат MOV A,L ;установка старшего ;двоично-десятичного байта RET CONV: XRA А ;сброс регистра А в нуль SBIT: DCR E ;уменьшение на 1 ;счетчика числа циклов RZ DAD H ;сдвиг старших разрядов ;в перенос ADC A DAA ;двоично-десятичная коррекция JNC SBIT ;двоично-десятичный ;байт больше 99? INX H ;да JMP SBIT Обратите внимание, как в строке с меткой CONV: устанавливается в нуль регистр А. Операция ИСКЛЮЧАЮЩЕЕ ИЛИ аккумулятора с самим собой обнулит его, а также сбросит и бит переноса. Заключение |
Что такое арифметические инструкции на языке ассемблера?
Хизар Хаят Саани
Устали от LeetCode? 😩
Изучите 24 шаблона, чтобы решить любой вопрос на собеседовании по кодированию, не заблудившись в лабиринте практических задач в стиле LeetCode. Практикуйте свои навыки в практической среде кодирования, не требующей настройки. 💪
Язык ассемблера — это язык программирования низкого уровня. Инструкции на языке ассемблера аналогичны инструкциям машинного кода.
Арифметические инструкции на языке ассемблера выполняются в арифметико-логическом устройстве (ALU) процессора компьютера.
В этом кадре мы будем обсуждать арифметические инструкции на языке ассемблера архитектуры машины x86 .
Типы арифметических инструкций
Язык ассемблера позволяет нам выполнять основные арифметические операции с целыми числами без знака. Это следующие операции:
- Сложение (
добавить
) - Вычитание (
sub
) - Умножение (
mul
) - Отдел (
отдел
)
Сложение и вычитание
Синтаксис для написания инструкций сложения или вычитания следующий:
назначение операции, источник
операция: предполагаемая арифметическая операция, т. е.
добавить
илизаменить
.назначение: регистр аккумулятора или ячейка памяти, где мы будем хранить наш окончательный результат после добавления или вычитания значения в исходном регистре или ячейке памяти.
источник: регистр или ячейка памяти, которая содержит значение, которое должно быть добавлено или вычтено из исходного содержимого регистра назначения .
Назначение и источник могут быть комбинацией следующего:
1. Зарегистрируйтесь, чтобы зарегистрировать
mov ax, 10 # переместите 10, чтобы зарегистрировать 'ax' mov bx, 5 # переместите 5, чтобы зарегистрировать 'bx' добавить топор, бх
2. Память для регистрации
mov ax, 10 # перемещение 10 для регистрации 'ax' add axe, [num1] # доступ к значению, хранящемуся в ячейке num1, и сохранение суммы # снова в регистре 'ax'
3. Зарегистрировать в памяти
mov ax, 10 добавить [число1], топор
4. Константа для регистрации
mov ax, 10 add ax, 5 # добавить 5 к значению регистра 'ax' и сохранить сумму в 'ax'
5. Константа в память
добавить [num1], 5 # добавить 5 к значению, хранящемуся в num1, и заменить значение # там с суммой
Мы также можем применить вышеуказанные комбинации источника/получателя к умножению и делению, где это применимо.
Дополнительные инструкции языка ассемблера, сопоставленные с языком высокого уровня
Увеличение и уменьшение
Инструкции inc
и dec
могут использоваться для inc
rement или dec
rement содержимое соответствующих операндов на единицу.
Инструкция inc
не влияет на флаг переноса.
Инструкция dec
устанавливает флаг нуля , если результат операции равен 0
.
Умножение и деление
Синтаксис для записи инструкций умножения или деления следующий:
источник операции
мул
выполняет беззнаковое умножение исходного операнда и аккумулятора.
Если исходным операндом является байт (8 бит), мы умножаем его на значение, хранящееся в регистре AL
. Результат возвращается в регистры AH
и AL
. Старшая половина 16-битного результата сохраняется в AH
, а младшая половина — в AL
. Это означает, что если результат достаточно мал, чтобы быть представленным в 8 битах, AH
будет содержать 0
.
Если исходным операндом является слово (16 бит), то мы умножаем его на значение, хранящееся в регистре AX
и результат возвращается в регистры DX
и AX
. Старшая половина 32-битного результата сохраняется в DX
, а младшая половина — в AX
.
Варианты инструкции mul
div
выполняет целочисленное деление аккумулятора и исходного операнда. Результат состоит из целочисленного частного и остатка.
Если исходным операндом является байт, 16-битное число, хранящееся в AX
, делится на операнд. 8-битное частное хранится в AL
, а 8-битный остаток в AH
.
Если исходным операндом является слово, 32-битное число, хранящееся в DX : AX
, делится на операнд. Старшая половина числа хранится в DX
, а младшая — в AX
. 16-битное частное хранится в AX
, а остаток в ДХ
.
Варианты инструкции div
Код
Следующий код показывает, как мы можем реализовать арифметические инструкции на языке ассемблера:
# программа для отображения арифметических инструкций в AL
# дополнение
# load ax, 5 # load ax, 5 # число в ax
mov bx, 2 # число загрузки в bx
add ax, bx # накопление суммы в ax
# вычитание
mov cx, 10
mov dx, 3
# накопление разности sub cx, dx в сх
# освежающие регистры
Move Axe, 0
Mov BX, 0
Mov CX, 0
MOV DX, 0
# Умножение - 8 -битный источник
MOV, 5
MOV BL, 10
mul bl # результат в ax
# обновление регистров
mov ax, 0
mov bx, 0
# умножение - 16-битный источник in dx:ax
# обновление регистров
MOV AX, 0
MOV BX, 0
# Divison - 8 -битный источник
MOV AL, 23
MOV BL, 4
DIV BL # COUTITION в AL, оставшееся в AH
# Регистры обновления
mov ax, 0
mov bx, 0
# деление - 16-битный источник завершить программу
int 0x21
СВЯЗАННЫЕ ТЭГИ
язык ассемблера
УЧАСТНИК
Хизар Хаят Саани
Copyright © 2023 Educative, Inc. Все права защищены раздел .текст глобальный _start _Начало: мов акс,4 мов ebx,2 ;добавление добавить eax, ebx добавить eax,’0′ mov [сумма],eax ;печатать сообщение мов эдкс, лен mov ecx, msg мов ebx,1 мов акс,4 интервал 0x80 ;печатать сумму мов эдкс, 1 mov ecx, сумма мов ebx,1 мов акс,4 интервал 0x80 ;выход мов ebx,0 мов акс,1 интервал 0x80 раздел .данные msg db «Сумма:» len equ $ — msg раздел .bss сумма соотв. 1
STDIN
STDINВывод:
Сумма: 6
создано 8 месяцев назад Venom Viper
Пишите, запускайте и делитесь кодом сборки онлайн с помощью онлайн-компилятора OneCompiler’s Assembly бесплатно. Это один из надежных, многофункциональных онлайн-компиляторов для языка ассемблера. Начать работу с компилятором сборки OneCompiler просто и довольно быстро. Редактор показывает образец стандартного кода, когда вы выбираете язык как Assembly
и приступайте к кодированию.
Язык ассемблера (asm) — это язык программирования низкого уровня, в котором языковые инструкции будут больше похожи на инструкции машинного кода.
Каждый ассемблер может иметь свой язык ассемблера, предназначенный для конкретного компьютера или операционной системы.
Язык ассемблера требует меньше времени выполнения и памяти. Это более полезно для прямого манипулирования оборудованием, критически важных приложений в реальном времени. Используется в драйверах устройств, низкоуровневых встраиваемых системах и т. д.
Язык ассемблера обычно состоит из трех разделов,
Раздел данных
Для инициализации переменных и констант, размер буфера, эти значения не меняются во время выполнения.
секция bss
Для объявления переменных
текстовая секция
_start
указывает начало этой секции, где фактически написан код.
Переменные
Существуют различные директивы определения для выделения пространства для переменных как для инициализированных, так и для неинициализированных данных.
1. выделить пространство для хранения на инициализированные данные
Синтаксис
.1 байт DW Определить слово 2 байта DD Определить двойное слово 3 70370 DQ Define Quadword 8 bytes DT Define Ten Bytes 10 bytes 2. To allocate storage space to un-initialized data
Define Directive | Описание |
---|---|
RESB | Резерв a Байт |
RESW | Резерв a Word | RE | 0375 |
RESQ | Reserve a Quadword |
REST | Reserve a Ten Bytes |
Constants
Constants can be defined using
1. equ
- To define numeric constants
CONSTANT_NAME EQU регулярное выражение или значение