# Assembler. Основные команды. ссылки * [Лекции](https://www.sites.google.com/site/sistprogr/lekcii1) ## Регистры 1. регистры общего назначения (АХ, ВХ, СХ, DX, SI, DI, BP, SP); 2. сегментные регистры (CS, DS, SS, ES); 3. указатель команд (IP); 4. регистр флагов (Flags). ![](https://i.imgur.com/zTli1Ck.png) Например: RAX= 64бит = 2^64 = 18 446 744 073 709 551 616 максимальное беззнаковое число EAX= 32бит = 2^32 = 4 294 967 296 максимальное беззнаковое число AX = 16бит = 2^16 = 65 536 максимальное беззнаковое число AL = 8 бит = 2^8 = 256 максимальное беззнаковое число ## Переменные применение ``` имя DB значение имя DW значение ``` db - 1 байт dw - 2 байта dd - 4 байта. ## Основные команды ### mov (способы адресации) Регистровая адресация. `mov ax, bx ;копируем содержимое bx в ax` Непосредственная адресация. `mov ax, 2 ;помещает в регистр АХ число 2.` Прямая адресация. Если нужно обратиться к ячейке памяти с известным абсолютным адресом, то этот адрес можно непосредственно указать в качестве операнда в `[]` ``` mov DL,meml ;Содержимое байта памяти с символическим именем meml mov AX, 0 ;Настроим сегментный регистр ES на mov ES,AX ;самое начало памяти (адрес 0) mov AX,ES:[0] ;АХ=содержимое слова с адресом 0000h:0000h mov DX,ES:[2] /DХ=содержимое слова с адресом 0000h:0002h ``` [***Остальное по адрессации читать тут***](https://www.sites.google.com/site/sistprogr/lekcii1/lek5) ## Арифмитические команды ### Сложение add/adc ``` add ax,5 ;AX = AX + 5 add dx,cx ;DX = DX + CX add dx,cl ;Ошибка: разный размер операндов. ADC ax,5 ;сложение с переносом ``` Пример: ``` //Сложение двух чисел с учетом переноса: FFFFFFAA + FFFF //помещаем числа в регистры mov eax, 0FFFFFFAAh mov ebx, 0FFFFh //зануляе регистры(более правильно - XOR AX,AX) mov edx, 0 mov ecx, 0 // складываем их add eax, ebx adc edx, ecx // заносим ответ в переменные а и b mov a, edx mov b, eax ``` ### Вычитание sub ``` sub ax,13 ;AX = AX - 13 sub ax,bx ;AX = AX + BX sub bx,cl ;Ошибка: разный размер операндов. ``` ### Инкремент и декремент. ``` inc ax ;AX = AX + 1 dec ax ;AX = AX - 1 ``` ### Умножение и деление. #### MUL – команда умножения чисел без знака. У этой команды только один операнд — второй множитель, который должен находиться в регистре или в памяти. Местоположение первого множителя и результата задаётся неявно и зависит от размера операнда: ![](https://i.imgur.com/sUUWK0W.png) Отличие умножения от сложения и вычитания в том, что разрядность результата получается в 2 раза больше, чем разрядность сомножителей. Примеры: mul bl ;AX = AL * BL mul ax ;DX:AX = AX * AX Если старшая часть результата равна нулю, то флаги CF и ОF будут иметь нулевое значение. В этом случае старшую часть результата можно отбросить. #### IMUL – команда умножения чисел со знаком. Эта команда имеет три формы, различающиеся количеством операндов: 1. С одним операндом — форма, аналогичная команде MUL. В качестве операнда указывается множитель. Местоположение другого множителя и результата определяется по таблице. 2. С двумя операндами — указываются два множителя. Результат записывается на место первого множителя. Старшая часть результата в этом случае игнорируется. Кстати, эта форма команды не работает с операндами размером 1 байт. 3. С тремя операндами — указывается положение результата, первого и второго множителя. Второй множитель должен быть непосредственным значением. Результат имеет такой же размер, как первый множитель, старшая часть результата игнорируется. Это форма тоже не работает с однобайтными множителями. Примеры: ``` imul cl ;AX = AL * CL imul bx,ax ;BX = BX * AX imul cx,-5 ;CX = CX * (-5) imul dx,bx,134h ;DX = BX * 134h ``` CF = OF = 0, если произведение помещается в младшей половине результата, иначе CF = OF = 1. Для второй и третьей формы команды CF = OF = 1 означает, что произошло переполнение. #### DIV – команда деления чисел без знака. У этой команды один операнд — делитель, который должен находиться в регистре или в памяти. Местоположение делимого, частного и остатка задаётся неявно и зависит от размера операнда: ![](https://i.imgur.com/NDBqqU7.png) При выполнении команды DIV может возникнуть прерывание (в данном курсе прерывания мы рассматривать не будем поэтому старайтесь избегать таких случаев): если делитель равен нулю; если частное не помещается в отведённую под него разрядную сетку (например, если при делении слова на байт частное больше 255). Примеры: ``` div cl ;AL = AX / CL, остаток в AH div di ;AX = DX:AX / DI, остаток в DX ``` #### IDIV – команда деления чисел со знаком. Единственным операндом является делитель. Местоположение делимого и частного определяется также, как для команды DIV. Эта команда тоже генерирует прерывание при делении на ноль или слишком большом частном. #### NOP – ничего не делающая команда. Примеры: `nop` mov bx, 5 //BL = 5 add bx, 8 //BL = BL + 8 | 13 sub bx, 1 //BL = BL - 1 | 12 mov al, 2 //AL = 2 mov cl, 3 //CL = 3 mul cl //AX = AL * CL | 6 //AX = 6, BL = 12 xchg bx, ax //AX = 12, BX = 6 mov dx, 0 div bx [Источник](https://www.sites.google.com/site/sistprogr/lekcii1/lek7)