32-битное умножение

Автор: xrnd | Рубрика: Исходники | 31-07-2010

Эта статья посвящена разбору примера умножения 32-битных чисел на 16-битном процессоре. Как вы наверно знаете, команда MUL в 16-битном режиме позволяет умножать максимум 16-битные значения, поэтому для умножения 32-битных чисел необходим специальный алгоритм.

Умножать большие числа приходится по частям, а затем складывать эти промежуточные результаты. Чтобы всё стало понятно я напишу небольшую формулу. Допустим, нам надо умножить два 32-битных числа a и b. В результате должно получиться 64-битное число c. Обозначим как a1 – младшее слово a, a2 – старшее слово a, b1 – младшее слово b, b2 – старшее слово b. Тогда получается:

a = (a2<<16) + a1

b = (b2<<16) + b1

Символы <<16 обозначают сдвиг влево на 16 бит. По сути это то же самое, что умножить на 65536.

c = a x b = ((a2<<16) + a1) x ((b2<<16) + b2) =
= (a1 x b1) + ((a2 x b1)<<16) + ((a1 x b2)<<16) + ((a2 x b2)<<32)

Алгоритм очень напоминает способ умножения в столбик. Графически можно изобразить следующим образом:

Читать полностью »

Учебный курс. Часть 22. Вывод чисел на консоль

Автор: xrnd | Рубрика: Исходники, Учебный курс | 31-07-2010

В качестве примера программирования процедур займёмся такой важной проблемой, как вывод на консоль чисел в различных системах счисления. Проблема эта возникает потому, что в ассемблере нет никаких специальных средств для вывода чисел, а с помощью стандартных функций можно выводить только строки.

Следовательно, задача сводится к тому, чтобы преобразовать двоичное число в строку символов, а затем вывести эту строку на экран. Все процедуры в этой части являются лишь примерами, вы можете использовать их или написать свои собственные процедуры, более удобные для вас.

Для начала рассмотрим две полезные процедуры, которые будут использоваться в дальнейшем. Чтобы постоянно не обращаться в коде в функции DOS 09h, удобно написать маленькую процедуру для вывода строки:

;Процедура вывода строки на консоль
; DI - адрес строки
print_str:
    push ax
    mov ah,9                ;Функция DOS 09h - вывод строки
    xchg dx,di              ;Обмен значениями DX и DI
    int 21h                 ;Обращение к функции DOS
    xchg dx,di              ;Обмен значениями DX и DI
    pop ax
    ret

Читать полностью »

Учебный курс. Часть 21. Простые процедуры

Автор: xrnd | Рубрика: Учебный курс | 08-07-2010

В этой части учебного курса мы рассмотрим основы создания процедур. Процедура представляет собой код, который может выполняться многократно и к которому можно обращаться из разных частей программы. Обычно процедуры предназначены для выполнения каких-то отдельных, законченных действий программы и поэтому их иногда называют подпрограммами. В других языках программирования процедуры могут называться функциями или методами, но по сути это всё одно и то же 🙂

Команды CALL и RET

Для работы с процедурами предназначены команды CALL и RET. С помощью команды CALL выполняется вызов процедуры. Эта команда работает почти также, как команда безусловного перехода (JMP), но с одним отличием – одновременно в стек сохраняется текущее значение регистра IP. Это позволяет потом вернуться к тому месту в коде, откуда была вызвана процедура. В качестве операнда указывается адрес перехода, который может быть непосредственным значением (меткой), 16-разрядным регистром (кроме сегментных) или ячейкой памяти, содержащей адрес.

Читать полностью »

Учебный курс. Часть 20. Стек

Автор: xrnd | Рубрика: Учебный курс | 31-05-2010

Стеком называется структура данных, организованная по принципу LIFO (“Last In – First Out” или “последним пришёл – первым ушёл”). Стек является неотъемлемой частью архитектуры процессора и поддерживается на аппаратном уровне: в процессоре есть специальные регистры (SS, BP, SP) и команды для работы со стеком.

Обычно стек используется для сохранения адресов возврата и передачи аргументов при вызове процедур (о процедурах в следующей части), также в нём выделяется память для локальных переменных. Кроме того, в стеке можно временно сохранять значения регистров.

Схема организации стека в процессоре 8086 показана на рисунке:

Читать полностью »

Справочник по FASM

Автор: xrnd | Рубрика: Новости | 13-05-2010

Добавил на сайт справочник по FASM. Спасибо, RoverWWWorm. Как я понял, это перевод официального мануала к FASM, который идёт вместе с компилятором. Единственное что, в справочнике описывается версия FASM 1.64. Возможно, какие-то директивы были добавлены или изменены в более новых версиях. Поэтому в случае сомнений обязательно сверяйтесь со свежим мануалом на английском 🙂

Скачать справочник можно в разделе «Файлы».

Учебный курс. Часть 19. Циклический сдвиг

Автор: xrnd | Рубрика: Учебный курс | 13-05-2010

Циклический сдвиг отличается от линейного тем, что выдвигаемые с одного конца биты вдвигаются с другой стороны, то есть движутся по кольцу. В процессора x86 существует 2 вида циклического сдвига: простой и через флаг переноса (CF). У всех команд, рассматриваемых в этой части учебного курса, по 2 операнда, таких же, как у команд линейного сдвига. Первый операнд – сдвигаемое значение и место для записи результата. Второй операнд – счётчик сдвигов, который может находится в регистре CL или указываться непосредственно.

Простой циклический сдвиг

Циклический сдвиг вправо выполняется командой ROR, а влево – командой ROL. Схема работы этих команд представлена на рисунке (на примере 8-битного операнда):

Читать полностью »

Учебный курс. Часть 18. Линейный сдвиг

Автор: xrnd | Рубрика: Учебный курс | 07-05-2010

Сдвиги – это особые операции процессора, которые позволяют реализовать различные преобразования данных, работать с отдельными битами, а также быстро выполнять умножение и деление чисел на степень 2. В этой части мы рассмотрим операции линейного сдвига, а в следующей будут циклические.

Логический сдвиг вправо

Логический сдвиг всегда выполняется без учёта знакового бита. Для логического сдвига вправо предназначена команда SHR. У этой команды два операнда. Первый операнд представляет собой сдвигаемое значение и на его место записывается результат операции. Второй операнд указывает, на сколько бит нужно осуществить сдвиг. Этим операндом может быть либо непосредственное значение, либо регистр CL. Схема выполнения операции показана на рисунке:

Читать полностью »

Учебный курс. Часть 17. Команды LOOPZ и LOOPNZ

Автор: xrnd | Рубрика: Учебный курс | 05-05-2010

Кроме команды LOOP и команд условных переходов существуют ещё две команды, позволяющие организовывать циклы. Это команды LOOPZ (или её синоним LOOPE) и LOOPNZ (синоним – LOOPNE). Действие этих команд очень напоминает LOOP, за исключением того, что дополнительно анализируется флаг нуля ZF.

Переход к метке цикла осуществляется в том случае, если после декремента содержимое CX не равно 0 и выполняется условие: ZF=1 (для команды LOOPZ/LOOPE) или ZF=0 (LOOPNZ/LOOPNE).

Эти команды удобно использовать в алгоритмах, где цикл должен завершаться в двух случаях:

  • выполнено требуемое количество итераций;
  • выполнено некоторое условие досрочного завершения цикла.

Читать полностью »

Справочник по функциям MS-DOS

Автор: xrnd | Рубрика: Новости | 28-04-2010

Откопал у себя на диске древний справочник по функциям DOS, BIOS и аппаратным ресурсам. Он может быть полезен в дополнение к учебному курсу. В нём вы найдёте подробное описание функций операционной системы MS-DOS, функций BIOS, разных областей памяти и т.д. Почитайте, кому интересно.

Скачать справочник можно на странице «Файлы».

Комментарии и ссылки

Автор: xrnd | Рубрика: Новости | 27-04-2010

Недавно я основательно поработал над отображением комментариев. Теперь они смотрятся гораздо лучше. Кроме того, я сделал список всех статей рубрики «Учебный курс» на отдельной странице (наверно, вы уже заметили) и добавил ссылки для удобного перехода к следующей части «Учебного курса» (чтобы можно было читать по порядку). Сегодня я добавил на сайт страницу «ссылки». Пока там только одна ссылка, но если у вас есть сайт близкой тематики, можем обменяться ссылками с вами.