Сейчас на форуме: bartolomeo, -Sanchez- (+3 невидимых) |
eXeL@B —› Вопросы новичков —› Справочник по командам ассемблера |
. 1 . 2 . >> |
Посл.ответ | Сообщение |
|
Создано: 13 февраля 2006 23:42 · Личное сообщение · #1 Начал писать проги на асме буквально 2-3 дня назад и вот у меня возник такая проблема. Нужен справочник по командам асма. Не учебник, а именно справочник(с програмированием проблем не возникало, но чувствую, что команд я заню маловато). Перечень команд, что команда делает, какие регистры и флаги меняет и т.д. и .т.п. Но желательно, чтобы всё это было описано в минимальном, но достаточном для понимания объёме. Кто чё посоветует? |
|
Создано: 14 февраля 2006 00:01 · Личное сообщение · #2 |
|
Создано: 14 февраля 2006 00:05 · Личное сообщение · #3 |
|
Создано: 14 февраля 2006 00:07 · Личное сообщение · #4 №3 вы не можете отправмть пустое сообщение. Это, имхо, никому не нужно Класная надпись. 56aa_AZM.part3.rar.zip |
|
Создано: 14 февраля 2006 00:14 · Личное сообщение · #5 |
|
Создано: 14 февраля 2006 00:46 · Личное сообщение · #6 |
|
Создано: 14 февраля 2006 07:18 · Личное сообщение · #7 Подробную информацию об устройстве машинных команд смотри в документации на IA-32 от Intel (http://www.intel.com), том второй. Номера для поиска: 253665?? - том 1-й, 253666?? и 253667?? - том 2-й, глава "Instruction Format" 253668?? - том 3-й. Самый определённый источник среди русскоязычных, который я нашёл, - "Специальный справочник" Юрова. ----- Всем привет, я вернулся |
|
Создано: 14 февраля 2006 13:45 · Личное сообщение · #8 |
|
Создано: 14 февраля 2006 18:40 · Личное сообщение · #9 |
|
Создано: 14 февраля 2006 19:47 · Личное сообщение · #10 |
|
Создано: 14 февраля 2006 19:52 · Личное сообщение · #11 |
|
Создано: 15 февраля 2006 10:28 · Личное сообщение · #12 Klajnor пишет: т.ч. пока найду эту документацию потрачу кучу денег Чего там искать? Я ж номера дал. Вот прямая ссылка: Instruction Set Reference, A-M File Name/Size: 25366618.pdf 2229503 bytes Download From: download.intel.com/design/Pentium4/manuals/25366618.pdf Instruction Set Reference, N-Z File Name/Size: 25366718.pdf 1654166 bytes Download From: ftp://download.intel.com/design/Pentium4/manuals/25366718.pdf Mordred пишет: Ass_Yurov_Assembler.rar Это учебник, а я сказал "Спец. справочник". Вообще у Юрова трёхтомник: Издательство "Питер" Assembler. Учебник для вузов. 2-е издание - 637 с. Assembler. Практикум. 2-е издание - 399 с. Assembler. Специальный справочник. 2-е издание. - 416 с. Я себе купил бумагу и всем советую, тем более что у кого-то инет дорого стоит. ЗЫ А на халяву можно попробовать этот скачать (сам не смотрел): asm.shadrinsk.net/download/asmjurov.zip ----- Всем привет, я вернулся |
|
Создано: 15 февраля 2006 12:19 · Личное сообщение · #13 Bitfry пишет: Вообще у Юрова трёхтомник: Издательство "Питер" Assembler. Учебник для вузов. 2-е издание - 637 с. Assembler. Практикум. 2-е издание - 399 с. Assembler. Специальный справочник. 2-е издание. - 416 с. Очень хорошая подборка. Советую именно купить книги. С ними работать приятнее, чем в моник пялиться. ----- Сколько ни наталкивали на мысль – все равно сумел увернуться |
|
Создано: 15 февраля 2006 12:42 · Личное сообщение · #14 |
|
Создано: 16 февраля 2006 05:13 · Личное сообщение · #15 |
|
Создано: 17 февраля 2006 11:01 · Личное сообщение · #16 |
|
Создано: 23 февраля 2006 02:55 · Личное сообщение · #17 |
|
Создано: 23 февраля 2006 08:26 · Личное сообщение · #18 |
|
Создано: 23 февраля 2006 12:30 · Личное сообщение · #19 |
|
Создано: 26 февраля 2006 00:40 · Личное сообщение · #20 Вот ещё справочник: ААА ASCII-коррекция регистра АХ после сложения Команда ааа используется вслед за операцией сложения add в регистре AL двух неупакованных двоично-десятичных (BCD) чисел, если в АХ находится двухразрядное неупакованное двоично-десятичное число. Команда не имеет параметров. Она преобразует результат сложения в неупакованное двоично-десятичное число, младший десятичный разряд которого находится в AL. Если результат превышает 9, выполняется инкремент содержимого регистра АН. Команда воздействует на флаги AF и CF. Пример mov AX,0605h ; Неупакованное BCD 65 add AL,09h ;Неупакованное BCD 9, AX=060Eh ааа ;AX=0704h, неупакованное BCD 74 AAD ASCII-коррекция регистра АХ перед делением Команда aad используется перед операцией деления неупакованного двоично-десятичного (BCD) числа в регистре АХ на другое неупакован ное двоично-десятичное число. Команда не имеет параметров. Она преобразует делимое в регистре АХ в двоичное число без знака, чтобы в результате деления получились правильные неупакованные двоично-десятичные числа (частное в AL, остаток в АН). Команда воздействует на флаги SF, ZF и PF. Пример raov AX,0207h ;Неупакованное BCD 27 mov DL,06h ;Неупакованное BCD 6 aad ;AX=001Bh=27 div DL ;AX=0304h, т.е. 4 и З в остатке AAM ASCII-коррекция регистра АХ после умножения Команда aam используется вслед за операцией умножения двух неупакованных двоично-десятичных чисел. Команда не имеет параметров. Она преобразует результат умножения, являющийся двоичным числом, в правильное неупакованное двоично-десятичное (BCD) число, младший разряд которого помещается в AL, а старший - в АН. Команда воздействует на флаги SF, ZF и PF. Пример mov AL,08h ;Неупакованное BCD 8 mov CL,07h ;Неупакованное BCD 7 mul CL ;AX=0038h=56 aam ;AX=0506h, BCD 56 AAS ASCII-коррекция регистра AL после вычитания Команда aas используется вслед за операцией вычитания одного неупакованного двоично-десятичного числа (BCD) из другого в AL. Команда не имеет параметров. Она преобразует результат вычитания в неупакованное двоично-десятичное число. Если результат вычитания оказывается меньше 0, выполняется декремент содержимого регистра АН. Команда воздействует на флаги AF и CF; после ее выполнения AF=1, CF=1. Пример mov AX,0708h ;Неупакованное BCD 78 mov CL,09h ;Неупакованное BCD 9 sub AL,CL ;AX=07FFh aas ;AX=0609h, неупакованное BCD 69 ADC Целочисленное сложение с переносом Команда adc осуществляет сложение первого и второго операндов, прибаатяя к результату значение флага переноса CF. Исходное значение первого операнда (приемника) теряется, замещаясь результатом сложения. Второй операнд не изменяется. В качестве первого операнда команды adc можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команда adc (совместно с командой add) обычно используется для сложения 32-разрядных чисел. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF. Пример 1 mov AX,1125h adc AX,2C25h ;AX=3D4Bh, если CF был = 1 ;AX=3D4Ah, если CF был = 0 Пример 2 ; В полях данных: numlow dw 0FFFFh ;Младшая часть 2-го слагаемого numhigh dw 000Sh ;Старшая часть 2-го слагаемого ;Число 0005FFFFh=393215 ;В программном сегменте: mov AX,000Sh ;Младшая часть 1-го слагаемого mov BX,0002h ;Старшая часть 1-го слагаемого ;Число 00020005h=131077 add АХ,numlow ;Сложение младших частей. АХ=4, CF=1 adc BX, numhigh ;Сложение старших частей с ;переносом.ВХ:АХ=0008:0004h. ;Число 00080004h=524292 Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Команда adc с 32-разрядными операндами может использоваться для сложения 64-разрядных целых чисел. Пример ; В полях данных mem321 dd 0FFFFFFFFh ;Младшая часть 1-го слагаемого mem32h dd 98765432h ;Старшая часть 1-го слагаемого ; В программном сегменте mov EAX,1 ;Младшая часть 2-го слагаемого mov EBX,0 ;Старшая часть 2-го слагаемого add EAX,mem321 ;Складываем младшие половины ;Сумма=100000000Ь>32 бит ;EAX=000000h, перенос adc EBX,mem32h ;Складываем старшие половины ;и перенос. EBX=90000001h ;Сумма: 9876543300000000h ADD Целочисленное сложение Команда add осуществляет сложение первого и второго операндов. Исходное значение первого операнда (приемника) теряется, замещаясь результатом сложения. Второй операнд не изменяется. В качестве первого операнда команды add можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячей-ку памяти или непосредственное значение, однако не допускается опре-делять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команду add можно использовать для сложения как обычных целых чи-сел, так и двоично-десятичных (с использованием регистра АХ для хра-нения результата). Если складываются неупакованные двоично- десятич-ные (BCD) числа, после команды add следует использовать команду ааа; если складываются упакованные числа, то команду daa. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF. Пример 1 mov BX,lFFEh mov CX,3 add BX,CX ;BX=2001h, CX=0003h Пример 2 mov AX,25h add AX,12h ;AX=0037h Пример 3 ; В полях данных: mem dw 128 ;B программном сегменте: add mem,100 ;mem=228 Пример 4 mov AX,0507h ;BCD распакованное 57 add AL,05h ;BCD 5, AX=050Ch aaa ;AX=0602h, BCD 62 Пример 5 mov AL,57h ;BCD упакованное 57 add AL,05h ;BCD 5, AL=5Ch daa ;AL=62h, BCD 62 Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример mov EAX,98765432h add EAX,11111111h ; EAX=A9876543h AND Логическое И Команда and осуществляет логическое (побитовое) умножение первого операнда на второй. Исходное значение первого операнда (приемника) теряется, замещаясь результатом умножения. В качестве первого операнда команды and можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами. Команда воздействует на флаги SF, ZF и PF. Правила побитового умножения: Первый операнд-бит 0101 Второй операнд-бит 0011 Бит результата 0001 Пример 1 mov AX,0FFEh and AX,5555h ;AX=0554h Пример 2 ; В полях данных: mem dw 0С003h ;В программном сегменте: mov AX,700Eh and AX,mem ;AX=4002h Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример mov EDX, 0FA8 8 0 0 4 lh and EDX,0FF00000Fh ; EDX = FA000001h 386P+ ARPL Коррекция запрашиваемого уровня привилегий селектора Команда aprl сравнивает селектор с образцом, содержащим максимально допустимый уровень привилегий (обычно используется селектор CS) и устанавливает проверяемое значение в соответствии с меньшим из двух уровней привилегий. Если изменение уровня не потребовалось, флаг ZF сбрасывается, если потребовалось - устанавливается. В качестве первого операнда команды aprl может использоваться 16-разрядный регистр или слово памяти с проверяемым селектором; в качестве второго операнда - 16-разрядный регистр с селектором-образцом. 386+ BOUND Проверка индекса массива на выход за границы массива Команда bound проверяет, лежит ли указанный индекс, рассматриваемый, как число со знаком, внутри заданных вторым операндом границ. Если индекс выходит за границы массива снизу или сверху, генерируется прерывание с вектором 5. Первый операнд должен быть регистром, содержащим проверяемый индекс, второй - адресом поля памяти с двумя границами проверяемого массива. В команде bound допустимо использование как 16-битовых, так и 32-битовых операндов (но и первый, и второй операнды должны быть одного типа). 386+ BSF Прямое сканирование битов Команда bsf сканирует слово или двойное слово в поисках бита, равного 1. Сканирование выполняется от младшего бита (0) к старшему. Если в слове не найдено установленных битов, то устанавливается флаг ZF. Если установленные биты есть, то номер первого установленного бита заносится в указанный в команде регистр. Номером бита считается его позиция в слове, отсчитываемая от бита 0. В качестве первого операнда команды bsf следует указывать регистр, куда будет помещен результат сканирования, в качестве второго - регистр или ячейку памяти со сканируемым словом. В команде bsf допустимо использование как 16-битовых, так и 32-битовых операндов (но и первый, и второй операнды должны быть одного типа). Пример 1 mov BX,70h ;Анализируемое данное bsf АХ,ВХ ;АХ=4, ZF=0 Пример 2 mov SI,0 ;Анализируемое данное bsf BX,SI ;ZF=1, в ВХ прежнее значение Пример 3 mov SI,8 ;Анализируемое данное bsf BX,SI ;BX=3, ZF=1 Пример 4 ;В полях данных mem dw 9000h Анализируемое данное ;В программном сегменте: bsf AX, mem ;AX=000Ch=12, ZF=0 386+ BSR Обратное сканирование битов Команда bsf сканирует слою или двойное слово в поисках бита, равного 1. Сканирование выполняется от старшего бита (15 или 31) к младшему. Если в слове не найдено установленных битов, то устанавливается флаг ZF. Если установленные биты есть, то номер первого установленного бита заносится в указанный в команде регистр. Номером бита считается его позиция в слове, отсчитываемая от бита 0. В качестве первого операнда команды bsf следует указывать регистр, куда будет помещен результат сканирования, в качестве второго - регистр или ячейку памяти со сканируемым словом. В команде bsf допустимо использование как 16-битовых, так и 32-битовых операндов, но и первый, и второй операнды должны быть одного типа (за исключением случая, когда второй операнд - константа). Пример 1 mov BX,70h ;Анализируемое данное bsr AX,BX ;AX=6, ZF=0 Пример |
|
Создано: 26 февраля 2006 00:44 · Личное сообщение · #21 Пример 2 mov SI,0 ;Анализируемое данное bsr BX,SI ;ZF=1, в ВХ прежнее значение Пример 3 mov SI,8 ;Анализируемое данное bsf BX,SI ;BX=3, ZF=1 Пример 4 ; В полях данных mem dw 9000h ; Анализируемое данное ;В программном сегменте: bsr AX, mem ;AX=000Fh=15, ZF=0 486+ BSWAP Обмен байтов Команда bswap изменяет порядок байтов в своем единственном операнде, в качестве которого может выступать только 32-разрядный регистр общего назначения. Биты 7...0 обмениваются с битами 31...24, а биты 15... 18 с битами 23...16. Другими словами, нумерация байтов регистра изменяется на противополжную (вместо 3, 2, 1,0 - 0, 1, 2, 3). Команда не воздействует на флаги процессора. Пример mov ЕАХ, 01234567h bswapEAX ;EAX=67452301h 386+ ВТ Проверка бита Команда bt позволяет определить, установлен ли в заданном слове определенный бит. Анализируемое слово выступает в качестве первого операнда, номер бита - в качестве второго. Первым операндом команды bt может служить регистр или ячейка памяти, вторым - регистр или непосредственное значение. В команде допустимо использование как 16-битовых, так и 32-битовых операндов, но и первый, и второй операнды должны быть одного типа (за исключением случая, когда второй операнд - константа). Значение проверяемого бита копируется в флаг CF. Пример 1 mov AX,00FFh ;Анализируемое данное bt AX,5 ; бит 5=1, ZF=1 Пример 2 mov AX,00FFh ;Анализируемое данное bt AX,8 ;бит 8=0, ZF=0 Пример 3 mov AX,8001h ;Анализируемое данное mov BX,15 ;Номер проверяемого бита bt АХ,ВХ ;бит 15 = 1, ZF=1 Пример 4 ;В полях данных mem dw IFh ;Анализируемое данное ;В программном сегменте: bt mem, 4 ;бит 4 = 1, ZF=1 386+ ВТС Проверка и инверсия бита Команда btc проверяет определенный бит в слове, заданном первым операндом, копирует его значение в флаг CF и инвертирует. Номер бита выступает в качестве второго операнда. Первым операндом команды btc может служить регистр или ячейка памяти, вторым - регистр или непосредственное значение. В команде допустимо использование как 16-битовых, так и 32-битовых операндов, но и первый, и второй операнды должны быть одного типа (за исключением случая, когда второй операнд - константа). Пример 1 mov AX,00FFh ;Анализируемое данное btc АХ, 5 ;AX=00DFh Бит 5 был = 1 ;Сброс бита 5, ZF=1 Пример 2 mov AX,OOFFh /Анализируемое данное btc АХ, 8 ;AX=lFFh Бит 8 был = О ;Установка бита 8, ZF=0 Пример 3 mov AX,8001h ;Анализируемое данное mov BX,15 ;Номер проверяемого бита btc AX,BX ;AX=0001h, ZF=1 Пример 4 ; В полях данных mem dw IFh ;В программном сегменте: ; Анализируемое данное btc mem, I /mem=lEh, ZF=1 386+ BTR Проверка и сброс бита Команда btr проверяет определенный бит в слове, заданном первым операндом, копирует его значение в флаг CF и сбрасывает. Номер бита выступает в качестве второго операнда. Первым операндом команды btr может служить регистр или ячейка памяти, вторым - регистр или непосредственное значение. В команде допустимо использование как 16-битовых, так и 32-битовых операндов, но и первый, и второй операнды должны быть одного типа (за исключением случая, когда второй операнд - константа). Пример 1 mov AX,00Fh ;Анализируемое данное btr АХ, 5 ;AX=00DFh. Бит 5 был = 1 ;Сброс бита 5, ZF=1 Пример 2 mov AX,00FFh ;Анализируемое данное btr AX, 8 ;AX=0FFh Бит 8 был =0 ;Остался 0, ZF=0 Пример 3 mov AX,8001h ;Анализируемое данное mov BX,15 ;Номер проверяемого бита btr AX,BX ;AX=0001h Бит 15 был = 1 ;Сброс бита 15, ZF=1 Пример 4 ;В полях данных mem dw IFh ;В программном сегменте: ;Анализируемое данное btr mem,10 ;mem=lFh Бит 10 был = 0 ;Остался 0, ZF=0 386+ BTS Проверка и установка бита Команда bts проверяет определенный бит в слове, заданном первым операндом, копирует его значение в флаг CF и устанавливает. Номер бита выступает в качестве второго операнда. Первым операндом команды bts может служить регистр или ячейка памяти, вторым - регистр или непосредственное значение. В команде допустимо использование как 16-битовых, так и 32-битовых операндов, но и первый, и второй операнды должны быть одного типа (за исключением случая, когда второй операнд - константа). Пример 1 mov AX,OOFFh ;Анализируемое данное bts AX, 5 ;AX=OOFFh Бит 5 был = 1 ;Остался 1, ZF=1 Пример 2 mov AX,OOFFh ;Анализируемое данное bts AX, 8 ;AX=lFFh Бит 8 был = 0 ;Установка бита 8, ZF=0 Пример 3 mov AX,8001h ; Анализируемое данное mov BX,15 ;Номер проверяемого бита bts AX,BX ;AX=8001h Бит 15 был = 1 ;Остался 1, ZF=1 Пример 4 ; В полях данных mem dw IFh ; Анализируемое данное ;В программном сегменте: bts mem,10 ;mem=4lFh Бит 10 был = 0 ; Установка бита 10, ZF=0 CALL Вызов подпрограммы Команда call передает управление подпрограмме, сохранив перед этим в стеке смещение к точке возврата. Команда ret, которой обычно заканчивается подпрограмма, забирает из стека адрес возврата и возвращает управление на команду, следующую за командой call. Команда не воздействует на флаги процессора. Команда call имеет четыре модификации: - вызов прямой ближний (в пределах текущего программного сегмента); - вызов прямой дальний (вызов подпрограммы, расположенной в другом программном сегменте); - вызов косвенный ближний; - вызов косвенный дальний. Все разновидности вызовов имеют одну и ту же мнемонику call, хотя и различающиеся коды операций. Во многих случаях транслятор может определить вид вызова по контексту, в тех же случаях, когда это невозможно, следует использовать атрибутные операторы: near ptr - прямой ближний вызов; far ptr - прямой дальний вызов; word ptr - косвенный ближний вызов; dword ptr - косвенный дальний вызов. Команда call прямого ближнего вызова заносит в стек относительный адрес точки возврата в текущем программном сегменте и модифицирует IP так, чтобы в нем содержатся относительный адрес точки перехода в том же программном сегменте. Необходимая для вычисления этого адреса величина смещения от точки возврата до точки перехода содержится в коде команды, который занимает 3 байт (код операции E8h и смещение к точке перехода). Команда call прямого дальнего вызова заносит в стек два слова - сначала сегментный адрес текущего программного сегмента, а затем (выше, в слово с меньшим адресом) относительный адрес точки возврата в текущем программном сегменте. Далее модифицируются регистры IP и CS: в IP помещается относительный адрес точки перехода в том сегменте, куда осуществляется переход, а в CS - сегментный адрес этого сегмента. Обе эти величины берутся из кода команды, который занимает 5 байтов (код операции 9А1г, относительный адрес вызываемой подпрограммы и ее сегментный адрес). Косвенные вызовы отличаются тем, что адрес перехода извлекается не из кода команды, а из ячеек памяти; в коде команды содержится информация о том, где находится адрес вызова. Длина кода команды зависит от используемого способа адресации. Примеры прямого ближнего вызова call near ptr subl ;Вызов подпрограммы subl ;из того же сегмента call subl ;To же самое Косвенные ближние вызовы Пример 1 mov BX,offset subl ;ВХ=адрес подпрограммы call BX ;Вызов подпрограммы Пример 2 ; В полях данных: addr dw subl ;Ячейка с адресом подпрограммы ;В программном сегменте: call DS:addr ;Вызов подпрограммы call word ptr addr ;To же самое Пример 3 ;В полях данных: addr dw subl ;Ячейка с адресом подпрограммы ;В программном сегменте: mov SI,offset addr ;SI=адрес ячейки с адресом ;подпрограммы call [SI] ;Вызов подпрограммы Пример 4 ;В полях данных: tbl dw subl ;Ячейка с адресом ;подпрограммы 1 dw sub2 ;Ячейка с адресом ;подпрограммы 2 dw sub3 ;Ячейка с адресом ;подпрограммы 3 ;В программном сегменте: mov BX,offset tbl ;ВХ=адрес таблицы адресов ;подпрограмм mov SI, 2 ;SI=смещение к адресу sub2 call [BX] [SI] ;Вызов подпрограммы 2 Пример прямого дальнего вызова call far ptr subl ;Вызов подпрограммы sub2, ;расположенной в другом ;программном сегменте Косвенные дальние вызовы Пример 1 ;В полях данных: addr dd subl ;Поле с двухсловным ;адресом подпрограммы ;В программном сегменте: call DS:addr ;Вызов подпрограммы call dword ptr addr;To же самое Пример 2 ;В полях данных: addr dd subl ;Поле с двухсловным ;адресом подпрограммы ;В программном сегменте: mov DI,offset addr ;В1=адрес поля с адресом ;подпрограммы call [DI] ;Вызов подпрограммы Пример 3 ; В полях данных: tbl dd subl ;Адрес подпрограммы 1 dd sub2 ;Адрес подпрограммы 2 dd sub3 ;Адрес подпрограммы 3 ;В программном сегменте: mov SI,offset tbl ;DI=адрес таблицы адресов mov DI,8 ;Смещение к адресу sub3 call [SI] [DI] ;Вызов подпрограммы sub3 Допустимо использование дополнительных режимов адресации 32-разрядных процессоров. В 32-разрядных приложениях допустимо использование 32-битовых операндов. В защищенном режиме роль сегментного адреса выполняет селектор. Примеры call [EAX] ;Косвенный вызов call 8[ЕСХ] ;Косвенный вызов CBW Преобразование байта в слово Команда cbw заполняет регистр АН знаковым битом числа, находящегося в регистре AL, что дает возможность выполнять арифметические операции над исходным операндом-байтом, как над словом в регистре АХ. Команда не имеет параметров и не воздействует на флаги процессора. Пример 1 mov AL,5 cdw ;AX=0005h Пример 2 mov AL, - 2 ;AL=FEh=-2 (байт) cdv ;AX=FFFEh=-2 (слово) 386+ CDQ Преобразование двойного слова в четверное Команда cdq расширяет знак двойного слова в регистре ЕАХ на регистр EDX. Эту команду можно использовать для образования четырехсловного делимого из двухсловного перед операцией двухсловного деления. Команда не имеет параметров и не воздействует на флаги процессора. Пример 1 ;В полях данных mem dd -2 ; Отрицательное число ;В программном сегменте mov ЕАХ,mem ;EAX=FFFFFFFEh cdq ;EDX=FFFFFFFFh, EAX=FFFFFFFEh Пример 2 ;В полях данных mem dd 7FFFFFFEh ,'Положительное число ;В программном сегмен |
|
Создано: 26 февраля 2006 00:45 · Личное сообщение · #22 ;В программном сегменте mov ЕАХ,mem ;EAX=7FFFFFFEh cdq ;EDX=00000000h, EAX=7FFFFFFEh CLC Сброс флага переноса Команда clc сбрасывает флаг переноса CF в регистре флагов. Команда не имеет параметров и не воздействует на остальные флаги процессора. Пример clc ;CF=0, независимо от ;исходного состояния CLD Сброс флага направления Команда eld сбрасывает флаг направления DF в регистре флагов, устанавливая прямое (в порядке возрастания адресов) направление выполнения операций со строками (цепочками). Команда не имеет параметров и не воздействует на остальные флаги процессора. Пример cld ;DF=0, независимо от ;исходного состояния CL1 Сброс флага прерываний Команда sti сбрасывает флаг разрешения прерываний IF в регистре флагов, запрещая (до установки этого флага командой sti) все аппаратные прерывания (от таймера, клавиатуры, дисков и т.д.) Команда не запрещает процессору выполнение команды hit (реализация программных прерываний); также не запрещаются немаскируемые прерывания, поступающие на вход NMI микропроцессора. Команда не имеет параметров и не воздействует на остальные флаги процессора. Пример cli ;IF=0, независимо от ;исходного состояния 386Р+ CLTS Сброс флага переключения задачи в управляющем регистре 0 Команда cits сбрасывает флаг TS в регистре CR0. CMC Инвертирование флага переноса Команда сmс изменяет значение флага переноса CF в регистре флагов на обратное. Команда не имеет операндов и не воздействует на остальные флаги процессора. Пример cmc ;Состояние флага CF ;изменяется на обратное СМР Сравнение Сами операнды не изменяются. Таким образом, если команду сравнения записать в общем виде стр операнд_1, операнд_2 то ее действие можно условно изобразить следующим образом: операнд_1 - операнд_2 -> флаги процессора В качестве первого операнда команды сmр можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно, как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Обычно вслед за командой сmр стоит одна из команд условных переходов, анализирующих состояние флагов процесс сора. При сравнении чисел без знака необходимо использовать команды условных переходов, предназначенные для анализа чисел без знака (ja, jb и проч.). При сравнении чисел со знаком необходимо использовать команды условных переходов, предназначенные для анализа чисел со знаком (jl, jg и проч.). Пример 1 cmp АХ,10000 ;АХ-10000 je eqlOOOO ;Переход на метку eql0000, ;если АХ=10000 Пример 2 ;В полях данных: base dw 8002h ;В программном сегменте: cmp DX,base DX-base jb below ;Переход на метку below, ;если DX, рассматриваемое ;как число без знака, меньше ;числа без знака 8002h=32770 Пример 3 ;В полях данных: base dw 8002h ;В программном сегменте: cmp DX,base DX-base jl less ;Переход на метку less, если ;DX, рассматриваемое как ;число со знаком, меньше ;числа со знаком 8002h=-32766 Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример cmp EAX,8000000 Oh ja above ;Переход, если ;EAX=80000001h...FFFFFFFFh CMPS Сравнение строк CMPSB Сравнение строк по байтам CMPSW Сравнение строк по словам Команды предназначены для операций над строками (строкой называется последовательность байтов или слов памяти с любым содержимым). Они сравнивают по одному элементу каждой строки, фактически осуществляя вычитание второго операнда из первого и устанавливая в соответствии с результатом вычитания флаги CF, PF, AF, ZF, SF и OF. Команда cmpsb выполняет сравнение по байтам, команда cmpsw - по словам, а команда cmps может быть использована для сравнения как байтов, так и слов. В последнем случае размер сравниваемых элементов определяется их описанием (с помощью директив db или dw). Первый операнд адресуется через DS:SI, второй - через ESI. Таким образом, операцию сравнения можно условно изобразить следующим образом: (DS:SI) - (ESI) -> флаги процессора После каждой операции сравнения регистры SI и DI получают положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1 или 2 в зависимости от размера сравниваемых элементов (байт или слово). Вариант команды cmps имеет формат cmps строка_1, строка_2 (что не избавляет от необходимости инициализировать регистры DS:SI и ESI адресами строк строка_1 и строка_2 соответственно). В этом формате возможна замена сегмента первой строки: cmps ES:строка_ 1, строка_2 Рассматриваемые команды могут предваряться префиксами повторения repe/repz (повторять, пока элементы равны, т.е. до первого неравенства) и repne/repiiz (повторять, пока элементы не равны, т.е. до первого равенства). В любом случае выполняется не более СХ операций над последовательными элементами. После выполнения рассматриваемых команд регистры SI и DI указывают на ячейки памяти, находящиеся за теми (если DF=0) или перед теми (если DF=1) элементами строк, на которых закончились операции сравнения. Пример 1 ;В полях данных сегмента данных, адресуемого через DS: strl db 'FILE.001' ;1-я строка ;В полях данных сегмента данных, адресуемого через ES: str2 db 'FILE.012' ;2-я строка ;В программном сегменте: eld ;Сравнение вперед mov SI,offset strl ;DS:SI ® strl mov DI, off set str2 ;ESI ® str2 mov CX,8 ;Длина сравниваемых строк repe cmpsb ;Поиск различия в строках je equal ;Переход, если строки ;совпадают notequ: ;Продолжение, если строки ;не совпадают В примере 1 строки не совпадают, и команда je выполнена не будет. После завершения сравнения строк управление будет передано на метку notequ. Содержимое регистров в этой точке: СХ=1 (так как не выполнено сравнение одной последней пары символов), SI = <смещение strl> + 7, DI = <смещение strl> + 7 (выполнено сравнение 7 пар символов). Пример 2 ;В полях данных сегмента данных, адресуемого через DS: strl db '12345678*90' ;1-я строка ;В полях данных сегмента данных, адресуемого через ES: str2 db ' abcdefgh*ij' ;2-я строка ; В программном сегменте: cld ;Сравнение вперед mov SI,offset strl;DS:SI ' strl mov DI,offset str2;ESI ' str2 mov CX,11 ;Длина сравниваемых строк repne cmpsb ;Поиск первой пары ;одинаковых элементов jne notequ ;Переход, если таковой нет found: ;Продолжение, если пара ;одинаковых элементов найдена В примере 2 имеется пара одинаковых элементов (*) в позиции 8 от начата строк. Поэтому команда jne выполнена не будет. После завершения сравнения строк управление будет передано на метку found. Содержимое регистров в этой точке: СХ=2 (так как не выполнено сравнение двух последних пар символов), SI = <смещение strl> + 9, DI = <смешенис strl> + 9 (выполнено сравнение 9 пар символов). Пример 3 ;В полях данных сегмента, адресуемого через ES: strl db '09.12.1998' ;1-я строка str2 db '09.12.1998' ;2-я строка ;В программном сегменте: eld ;Сравнение вперед mov SI, off set strl ;DS:SI -> strl mov DI,offset str2 ;ESI -> str2 mov CX,10 ;Длина сравниваемых строк repe cmps ES:str1,ES:str2 ;Поиск различия в строках je equal ; Переход, если строки ;одинаковы notequal: ;Продолжение, строки ;различаются В примере 3 строки одинаковы и после завершения сравнения управление будет передано на метку equal. Поскольку строки описаны с помощью директив db, фактически выполняется команда cmpsb, т.е. побайто вое сравнение. Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. 386+ CMPSD Сравнение строк по двойным словам Команда аналогична командам МП 86 cmpsb и cmpsw, но позволяет сравнивать 32-битовые участки строк, адресуемых через регистры DS:ESI и ES:EDI (или, в 16-разрядных приложениях, через DS:SI и ESI). Использование мнемоники cinpsd с префиксом rep не означает, что в качестве счетчика будет автоматически использоваться расширенный регистр ЕСХ. Пример ;В полях данных сегмента, адресуемого через DS areal dd 152345,168666,954333 area2 dd 152345,168666,954331 ;B программном сегменте push DS pop ES ;ES=DS mov SI,offset areal ;DS:SI ->areal mov DI,offset area2 ;ESI ->area2 mov CX,3 ;Будем сравнивать З числа repe cmpsd je equal В приведенном примере в строках (фактически это целочисленные массивы) различаются последние элементы, и команды jc выполнена не будет. |
|
Создано: 26 февраля 2006 00:46 · Личное сообщение · #23 486+ CMPXCHG Сравнение и обмен Команда cmpxchg выполняет в одной операции сравнение и обмен операндов. Команда требует два параметра и неявным образом использует третий операнд - регистр ЕАХ. Первый операнд (приемник) должен находиться в 16- или 32-битовой ячейке памяти, второй операнд (источник) - в регистре общего назначения такого же размера. Команда выполняет сравнение операнда-приемника с содержимым неявного операнда - регистра ЕАХ. Если сравниваемые значения совпадают, операнд-приемник замещается операндом-источником (т.е. содержимое регистра записывается в память). Если сравниваемые значения не совпадают, содержимое памяти (приемник) поступает в регистр ЕАХ (рис. П1). Команда воздействует на флаги OF, SF, ZF, AF, PF и CF. Рис.П1. Действие команды cmpxchg Пример 1 ; В полях данных mem dw 135 ; В программном сегменте mov AX,135 mov BX,60 cmpxchg mem,BX ;mem=AX. Регистр ® память ; mem=60, BX=60, АХ=135 Пример 2 ; В полях данных mem dw 135 ;В программном сегменте mov AX,148 mov BX,60 cmpxchg mem,BX ;mem<>AX. Память ® АХ ;mem=135, BX=60, AX=148 Pentium+ CMPXCHG8B Сравнение и обмен 8 байтов Команда cmpxchgSb выполняет в одной операции сравнение и обмен 8-байтовых операндов. Команда требует один параметр и неявным образом использует еще два операнда - пары регистров EDX:EAX и ЕСХ:ЕВХ. В качестве явного операнда команды (приемника) может выступать только 64-битная (8-байтовая) ячейка памяти. Команда выполняет сравнение операнда-приемника в памяти с содержимым EDX:EAX. Если сравниваемые значения совпадают, то операнд-приемник в памяти замещается 64-битным значением ЕСХ:ЕВХ. Если сравниваемые значения не совпадают, содержимое памяти поступает в пару регистров EDXrEAX, замещая один из сравниваемых операндов (рис. П2). Команда воздействует на флаг ZF. Рис. П2. Действие команды cmpxchg8b Пример 1 ; В полях данных mem dq 1122334455667788h ;В программном сегменте mov ЕСХ,9 mov ЕВХ,5 mov EDX,11223344h mov EAX,55667788h cmpxchgSb mem ;mem=EDX:EAX. ECX:EBX ® mem ; mem=0000000900000005h Пример 2 ; В полях данных mem dq 1122334455667788h ;B программном сегменте mov ECX,9 mov EBX,5 mov EDX,11223344h mov EAX,55667789h cmpxchgSb mem ;memOEDX: EAX. Mem -" EDX : EAX ;mem=1122334455667788h ;EDX=11223344h, EAX=55667788h При работе с многобайтовыми данными не следует забывать о том, что в памяти байты любых данных всегда выстраиваются в порядке их номеров, т.е. от младшим к все более старшим, в то время как при изображении чисел мы применяем обратный порядок - сначала пишем старшие разряды числа, затем младшие. В то же время символьные строки мы изображаем так же, как они располагаются в памяти - для нас естественно считать, что по мере движения по строке вправо номер символа возрастает. Пример 3 ; В полях данных meml db '12345678' ;Строка-операнд mem2 db '12345678' ;Сравниваемая строка ;В программном сегменте mov ECX,68676665h ;'efgh' mov EBX,64636261h ;'abcd' mov EDX,dword ptr mem2+4 ;Забираем старшую ;часть строки mov EAX,dword ptr mem2 ;Забираем младшую ;часть строки cmpxchg8b gword ptr meml ;Операнды совпадают ;ZF=1, mem1=''abcdefgh'' ;ECX:EBX без изменений ;EDX:EAX без изменений Пример 4 ;В полях данных meml db '12345678' ;Строка-операнд mem2 db 'abcdefgh' ;Сравниваемая строка ; В программном сегменте mov ECX,68676665h ;'efgh' mov EBX,64636261h ;'abed' mov EDX,dword ptr mem2+4 ;3абираем старшую ;часть строки mov EAX,dword ptr mem2 ;Забираем младшую ;часть строки cmpxchg8b qword ptm mem1 ;Операнды не совпадают ;ZF=0, EDX=38373635='5678' ;EAX=34333231='1234' ;mem1s без изменения ;При неравенстве ЕСХ:ЕВХ не принимают участие в операции Pentium+ CPUID Идентификация процессора Команда cpuid позволяет получить код идентификации процессора, установленного на данном компьютере. Команда в качестве неявного операнда использует регистр ЕАХ. Для процессоров Pentium регистр ЕАХ перед вызовом команды cpuid может принимать два значения: 0 и 1. Если ЕАХ=0, то команда возвращает в регистре ЕАХ код 1, а в регистрах ЕВХ, EDX и ЕСХ (именно в таком порядке) - три части символьной строки, идентифицирующей изготовителя процессора. Для процессоров Intel возвращаемая строка в целом имеет вид "Genumclatcl". Если перед вызовом команды cpuid значение ЕАХ равно 1, то команда возвращает в регистре ЕАХ коды разработки конкретной версии процессора, а в регистре EDX код IBFli, содержащий информацию о возможностях процессора. Коды разработки в регистре ЕАХ хранятся в следующем формате: биты 0 ... 3 - номер поколения (например, 3); биты 4 ... 7 - модель (например, 4); биты 8 ... 11 - семейство (5 для Pentium). Содержимое регистра EDX включает конфиденциальную информацию изготовителя, а также говорит о наличии на кристалле микропроцессора арифметического сопроцессора (бит 0) и поддержке команды cmpxchgSb (бит 8). Пример ;В полях данных mem dd 0,0,0 ;В программном сегменте mov ЕАХ,О cpuid ;EAX=0001h mov mem, ЕВХ mov mem+4, EDX mov mem+8, ECX ;mem='Genuinelntel' cpuid EAX=543h (например) ,EDX = lBFh CWD Преобразование слова в двойное слово Команда cwd заполняет регистр DX знаковым битом содержимого регистра АХ, преобразуя тем самым 16-разрядное число со знаком в 32-разрядное, размещаемое в регистрах DX:AX. Команду удобно использовать для преобразования двухбайтового делимого в четырехбайтовое (двойное слово) при делении на 16-разрядный операнд. Команда не имеет параметров и не воздействует на флаги процессора. Пример 1 mov AX,32767 ;AX=7FFFh cwd ;AX=7FFFh, DX=OOOOh. ;DX:AX=32767 Пример 2 mov AX,-32768 ;AX=8000h cwd ;AX=8000h, DX=FFFFh. ;DX:AX=-32768 386+ CWDE Преобразование слова в двойное слово с расширением Команда cwde заполняет старшую половину регистра ЕАХ знаковым битом содержимого регистра АХ, преобразуя тем самым 16-разрядное число со знаком в 32-разрядное, размещаемое в расширенном регистре ЕАХ. Команда не имеет операндов и не воздействует на флаги процессора. Пример ; В полях данных mem dw - 3 ;В программном сегменте mov AX,mem ;AX=FFFD cwde ;EAX=FFFFFFFDh DAA Десятичная коррекция в регистре AL после сложения Команда daa корректирует результат сложения в регистре AL двух упакованных двоично-десятичных (BCD) чисел (по одной цифре в каждом полубайте), чтобы получить пару правильных упакованных двоично-десятичных цифр. Команда используется вслед за операцией сложения упакованных двоично-десятичных чисел. Если результат сложения превышает 99, возникает перенос и устанавливается флаг CF. Команда воздействует на флаги SF, ZF, AF, PF и CF. Пример 1 mov AL,87h ;Упакованное BCD 87 add AL,04h ;После сложения AL=8Bh daa ;AL=91h, т.е. упакованное BCD 91 Пример 2 mov AL,87h ;Упакованное BCD 87 add AL,11h ;После сложения AL=97h daa ;AL=97h, т.е. упакованное ;BCD 97 (в данном случае ;команда daa ничего не делает) DAS Десятичная коррекция в регистре AL после вычитания Команда das корректирует результат вычитания в регистре AL двух упакованных двоично-десятичных (BCD) чисел (по одной цифре в каждом полубайте), чтобы получить пару правильных упакованных десятичных цифр. Команда используется вслед за операцией вычитания упакованных двоично-десятичных чисел. Если для вычитания требовался заем, устанавливается флаг CF. Команда воздействует на флаги SF, ZF, AF, PF и CF. Пример 1 mov AL,55h ;Упакованное BCD 55 sub AL,19h ;После вычитания AL=3Ch das ;AL=36h, т.е. упакованное BCD 36 Пример 2 mov AL,55h ;Упакованное BCD 55 sub AL,15h ;После вычитания AL=40h das ;AL=40h, т.е. упакованное ;BCD 40 (в данном случае ;команда das ничего не делает) DEC Декремент (уменьшение на 1) Команда dec вычитает 1 из операнда, в качестве которого можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Операнд интерпретируется как число без знака. Команда воздействует на флаги OF, SF, ZF, AF и PF. Пример 1 mov AX,0FFFFh dec AX ;AX=FFFEh Пример 2 mov CX,0 dec CX ;CX=FFFFh Пример 3 mov CX,3500h dec CL ;CX=35FFh Пример 4 ; В полях данных mem dw 68 ;B программном сегменте dec mem mem=67 Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример mov EAX, 0 dec EAX ;EAX=FFFFFFFFh DIV Деление целых чисел без знака Команда div выполняет деление целого числа без знака, находящегося в регистрах АХ (в случае деления на байт) или DX:AX (в случае деления на слово), на операнд-источник (целое число без знака). Размер делимого в два раза больше размеров делителя и остатка. Для однобайтовых операций делимое помещается в регистр АХ; после выполнения операции частное записывается в регистр AL, остаток - в регистр АН. Для двухбайтовых операций делимое помещается в регистры DX:AX (в DX - старшая часть, в АХ - младшая); после выполнения операции частное записывается в регистр АХ, остаток - в регистр DX. В качестве операнда-делителя команды div можно указывать регистр (кроме сегментного) или ячейку памяти; не допускается деление на непосредственное значение. Если делитель равен 0, или если частное не помещается в назначенный регистр, возбуждается прерывание с вектором 0. Команда не воздействует на флаги процессора. Команду div можно использовать для целочисленного деления неупакованного двоично-десятичного числа в регистре АХ не неупакованный двоично-десятичный делитель, если перед ней выполнить команду aad (см. пример 3). Пример 1 mov AX,506 ;Делимое mov BL,50 ;Делитель div BL ;AL=0Ah (частное), AH=06h (остаток) Пример 2 ; В полях данных long dd 65537 ;Делимое ;В программном сегменте mov DX,word ptr long+2 ;DX=0001h, старшая ;часть делимого mov AX,word ptr long ;AX=0001h, младшая ;часть делимого mov CX,256 ;Делитель div CX ;AX=0100h (частное), ;DX=0001h (остаток) Пример З mov AX,0807h ;Неупакованное BC |
|
Создано: 26 февраля 2006 00:48 · Личное сообщение · #24 mov DL,09h ;Неупакованное BCD 9 aad ;AX=0057h=87 div DL ;AX=0609h, т.е. 9 и 6 в остатке Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. При этом, если делитель представляет 32-битовую величину, то возможен только один вариант команды деления, когда делимое находится в парс регистров EDX:EAX. В этом случае частное будет помещено в регистр ЕАХ, остаток - в EDX. Пример mov ЕАХ, 0FFFFFFFh ;Младшая часть делимого mov EDX,0 ;Старшая часть делимого mov EBX,256 ;Делитель div EBX ;Частное в EAX=000FFFFFh, ;Остаток в EDX=000000FFh 386+ ENTER Создание стекового кадра для параметров процедуры Команда enter, обычно являющаяся первой командой процедуры, выделяет заданный объем стекового пространства для локальных (автоматических) параметров процедуры, предоставляя процедуре указатель на выделенную область (в качестве такого указателя используется регистр ЕВР) и смещая указатель стека ESP так, чтобы он указывал на начало свободного стекового пространства. В результате процедура имеет возможность обращаться по ходу своего выполнения к своим локальным параметрам и, в то же время, пользоваться оставшимся пространством стека для временного сохранения в нем любых данных с помощью команд push и pop. Команда leave в конце процедуры выполняет обратные действия, возвращая стек в исходное состояние и уничтожая область локальных переменных. Локальными, как известно, называются как раз те переменные, которые существуют только в течение времени выполнения некоторой процедуры, и автоматически исчезают после се завершения. Команды enter и leave используются многими языками высокого уровня для управления доступом к локальным переменным вложенных процедур. Команда enter имеет два операнда. Первый (16-битовое непосредственное значение) определяет число байтов, выделяемых в стеке для локальных переменных. Для 32-разрядных приложений место в стеке выделяется двойными словами (по 4 байт), для 16-разрядных - словами (по 2 байт). Второй операнд (8-битовос непосредственное значение) задаст так называемый лексический уровень процедуры, характеризующий степень ее вложенности. В зависимости от значения лексического уровня, команда enter выполняется по-разному. При лексическом уровне, равном 0, реализуется невложенная форма команды enter. В этом случае после входа в процедуру (командой call) с сохранением в стеке адреса возврата, в стек заносится текущее содержимое регистра ЕВР, в ЕВР копируется текущее значение указателя стека, а указатель стека смещается на число байтов, заданное первым операндом команды enter . Создаваемая на сте-ке структура носит название стекового кадра, а регистр ЕВР выполняет в данном случае функцию указателя стекового кадра. Подпрограмма имеет возможность обращаться к своим локальным переменным по адресам ESP-4 и ESP-8 (для случая резервирования места под две переменные). Занеся в стек по этим адресам некоторые данные (полученные в качестве параметров вызова через регистры общего назначения или созданные самостоятельно) подпрограмма может затем многократно к ним обращаться, не боясь их затирания в процессе использования стека. Поскольку команда enter настроила указатель стека на область, находящуюся за пределами локальных переменных, программа может использовать команды push для сохранения в стеке временных данных. Команда leave, размещаемая в самом конце процедуры, перед завершающей командой ret, копирует содержимое ЕВР в ESP, освобождая (в логическом плане) область локальных переменных, и снимает со стека сохраненное там исходное содержимое ЕВР. После этого командой ret можно вернуться в вызывающую процедуру. Поскольку первый параметр команды enter имеет размерность слова, процедура в принципе имеет возможность зарезервировать в стеке для своих локальных переменных до 64 Кбайт стекового пространства. Лексические уровни, отличные от 0, используются в тех случаях, когда по правилам языка высокого уровня каждая вложенная процедура имеет право обращаться к локальным переменным всех вышележащих процедур, но не к процедурам, находящимся на параллельных с ней ветвях вложенности. Другими словами, область видимости переменных распространяется на все вложенные процедуры, но две подпрограммы, вызываемые из одной и той же (вышележащей) процедуры, "не видят" друг друга. В таких случаях главной процедуре назначается лексический уровень 1, все вызываемые из нее подпрограммы получают значение лексического уровня 2, подпрограммы, вызываемые из этих процедур, имеют уровень 3 и т.д. Команды enter при ненулевом значения второго параметра создают в стеке стековые кадры с более сложной структурой. Отличие такого стекового кадра от рассмотренного выше заключается в том, что в него, помимо области локальных переменных, входят также указатели стековых кадров всех вышележащих процедур. В результате любая подпрограмма может с помощью своего указателя (т.е. содержимого ESP) обратиться к собственных! переменным, а используя хранящиеся в стеке указатели кадров вышележащих процедур, "дотянуться" и до их локальных переменных. По-прежнему команды leave освобождают стек от стековых кадров вместе со всеми находящимися в них данными. Пример ;Вызывающая процедура call subrl ;Подпрограмма subrl subrl proc enter2048,0 ;Место под локальные данные . . . ;Работа с локальными данными leave ret HLT Останов Команда hlt прекращает выполнение программы и переводит процессор в состояние останова. Работа процессора возобновляется после операции запуска, а также в случае прихода немаскируемого или разрешенного маскируемого прерываний. IDIV Деление целых чисел со знаком Команда IDIV выполняет деление целого числа со знаком, находящегося в регистрах АХ (в случае деления на байт) или DX:AX (в случае деления на слово), на операнд-источник (целое число со знаком). Размер делимого в два раза больше размеров делителя и остатка. Оба результата рассматриваются как числа со знаком, причем знак остатка равен знаку делимого. Для однобайтовых операций делимое помещается в регистр АХ; после выполнения операции деления частное записывается в регистр AL, остаток - в регистр АН. Для двухбайтовых операций делимое помещается в регистры DX:AX (в DX - старшая часть, в АХ - младшая); после выполнения операции деления частное записывается в регистр АХ, остаток - в регистр DX. В качестве операнда-делителя команды idiv можно указывать регистр данных или ячейку памяти; не допускается деление на непосредственное значение. Если делитель равен 0, или если частное не помещается в назначенный регистр, возбуждается прерывание через вектор 0. Команда не воздействует на флаги процессора. Пример 1 mov AX,506 ;Делимое mov BL,50 ;Делитель idiv BL ;AL=0Ah (частное), AH=06h ; (остаток) Рис.П3. Состояние стека после входа в подпрограмму и выполнения команды enter8,0(на рисунке адреса ячеек уменьшаются в низ) Пример 2 ;В полях данных long dd 0F0007h ;Делимое ; В программном сегменте mov DX,word ptr long+2;DX=000Fh, старшая ;часть делимого mov AX,word ptr long;AX=0007h, младшая ;часть делимого mov CX,256 ;Делитель idiv СХ ;AX=0F00h (частное), ;DX=0007h (остаток) Пример 3 mov AX,-506 ;AX=FE06h, делимое mov BL,50 ;Делитель idiv BL ;AL=F6h (-10), AH=FAh (-6) Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. При этом, если делитель представляет 32-битовую величину, то возможен только один вариант команды деления, когда делимое находится в парс регистров EDX:EAX. В этом случае частное будет помещено в регистр БАХ, остаток - в EDX. Пример ; В полях данных dvd dq -100001 Делимое ;B программном сегменте mov EAX,dword ptr dvd EAX=FFFE795Fh ;(младшая часть делимого) mov EDX,dword ptr dvd+4 EDX=FFFFFFFFh (старшая ;часть делимого) mov EBX,50 Делитель idiv EBX Частное в EAX=FFFFF830h= ;-2000, остаток в EDX=FFFFFFFFh=-1 IMUL Умножение целых чисел со знаком Команда IMUL выполняет умножение целого числа со знаком, находящегося в регистре AL (в случае умножения на байт) или АХ (в случае умножения на слово), на операнд-источник (целое число со знаком). Размер произведения в два раза больше размера сомножителей. Для однобайтовых операций один из сомножителей помещается в регистр AL; после выполнения операции произведение записывается в регистр АХ. Для двухбайтовых операций один из сомножителей помещается в регистр АХ; после выполнения операции произведение записывается в регистры DX:AX (в DX - старшая часть, в АХ - младшая). В качестве операнда-сомножителя команды imul можно указывать регистр (кроме сегментного) или ячейку памяти; не допускается умножение на непосредственное значение. Команда воздействует на флаги OF и CF. Если АН или DX представляют собой просто знаковое расширение AL или АХ, соответственно (т.е. результат умножения со знаком верен), OF и CF сбрасываются в 0; в противном случае (результат со знаком не помещается в АХ или DX:AX) OF и CF устанавливаются в 1. Пример 1 mov AL,5 ;Первый сомножитель mov BL,3 ;Второй сомножитель imul BL ;AX=000Fh (произведение) Пример 2 mov AX,256 ;Первый сомножитель mov BX,256 ;Второй сомножитель imul BX ;DX=0001h, AX=0000h ;(число 65536) Пример 3 mov AL,-5 ;AL=FBh mov BL,3 ;BL=03h imul BL ;AX-'FFF1h (-15) Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Имеются также варианты команды с двумя и тремя операндами. Для команды imul с одним операндом второй сомножитель должен располагаться в AL, АХ или ЕАХ. Процессор выбирает размерность второго сомножителя, исходя из размерности первого, указанного в качестве операнда. 16-, 32- или 64-битовый знаковый результат помещается в регистры АХ, DX:AX или EDX:EAX, соответственно. Если после операции умножения содержимое АН, DX или EDX является лишь знаковым расширением AL, АХ или ЕАХ, соответственно, то флаги CF и OF сбрасываются в 0. В противном случае они устанавливаются в 1. Для команды imul с двумя операндами их произведение записывается в первый операнд; второй операнд не изменяется. В качестве первого операнда могут выступать 16- или 32-разрядные регистры общего назначения; в качестве второго |
|
Создано: 26 февраля 2006 00:50 · Личное сообщение · #25 в качестве второго операнда - 16- или 32-разрядные регистры общего назначения, 16- или 32-битовые ячейки памяти или непосредственное значение. Оба операнда должны иметь один размер. Если результат умножения помещается в первый операнд, флаги CF и OF сбрасываются в 0. В противном случае они устанавливаются в 1. Для команды imul с тремя операндами произведение второго и третьего операндов записывается в первый операнд. В качестве первого операнда могут выступать 16- или 32-разрядные регистры общего назначения; в качестве второго операнда - 16- или 32-разрядные регистры общего назначения или 16- или 32-битовые ячейки памяти; в качестве третьего операнда - только непосредственное значение. Два первых операнда должны иметь один размер. Если результат умножения помещается в первый операнд, флаги CF и OF сбрасываются в 0. В противном случае они устанавливаются в 1. Пример 1 mov EAX,-1 ;Первый сомножитель mov ESI,100000000 ;Второй сомножитель imul ESI ;EDX=FFFFFFFFh, ;EAX=FA0AlF00h ;Результат=-100000000 Пример 2 ;В полях данных ор2 dd 100h ;Первый сомножитель ; В программном сегменте mov EAX,400000h ;Второй сомножитель imul EAX,op2 ;EAX=40000000h Пример 3 mov BX,300h imul АХ,ВХ,4 ;AX=300h*4=0C00h IN Ввод из порта Команда in вводит в регистр AL или АХ соответственно байт или слово из порта, указываемого вторым операндом. Адрес порта помещается в регистр DX. Если адрес порта не превышает 255, он может быть указан непосредственным значением. Указание регистра-приемника (AL или АХ) обязательно, хотя с другими регистрами команда in не работает, и их указывать нельзя. Команда не воздействует на флаги процессора. Пример 1 in AL, 60h ;Ввод байта из порта 60h Пример 2 mov DX,3D5h ;Адрес порта in AL,DX ;Ввод байта из порта 3D5h Допустимо использование в качестве операнда-приемника расширенного регистра ЕАХ (если адресуемое устройство позволяет прочитать из его порта двойное слово). Пример mov DX,345h ;Адрес порта in EAX,DX INC Инкремент (увеличение на 1) Команда inc прибавляет 1 к операнду, в качестве которого можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Операнд интерпретируется как число без знака. Команда воздействует на флаги OF, SF, ZF, AF и PF. Команда не воздействует на флаг CF; если требуется воздействие на этот флаг, необходимо использовать команду add op,l. Пример 1 mov AX,0563h inc AX ;AX=0564h Пример 2 mov BH,15h inc BH ;BH=16h Пример 3 mov AX,A5FFh inc AL ;AX=A500h inc AH ;AX=A600h Пример 4 mov AX,0FFFFh inc AX ;AX=0000h, ZF=1, CF=0 ;Для сравнения: mov CX,0FFFFh add CX,1 ;CX=0000h, ZF=1, CF=1 Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример ;В полях данных mem dd 12345678h ; В программном сегменте inc mem ;mem=12345679h NS Ввод строки из порта INSB Ввод байта из порта INSW Ввод слова из порта INSD Ввод двойного слова из порта Команды предназначены для ввода данных из порта непосредственно в память. Адрес порта указывается, как и для команды in, в регистре DX, при этом задание адреса порта непосредственным значением не допускается. Данные пересылаются по адресу, находящемуся в паре регистров ES:EDI. Замена сегмента не допускается. Команда insb переносит из порта 1 байт, команда insw - 1 слово, команда insd - 1 двойное слово, а команда ins может быть использована для передачи байтов, слов и двойных слов. В последнем случае размер загружаемого данного определяется описанием строки (с помощью директив db, dw или dd). После передачи данных регистр EDI получает положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1, 2 или 4, в зависимости от размера передаваемых данных. Вариант команды ins имеет формат ins строка, DX (что не избавляет от необходимости инициализировать регистры ES:EDI адресом строки). Если устройство, адресуемое через порт, может передавать последовательность данных, то команды ins можно предварить префиксом повторения rep. В этом случае из порта принимается СХ элементов данных заданного размера. Команды ins не воздействуют на флаги процессора. Пример ;В сегменте данных, адресуемых через DS mem dw 0 ;В программном сегменте push DS pop ES ;ES=DS mov DI,offset mem;ESI -> mem mov DX,303h ;Адрес порта insw ;Ввод из порта 16-битового данного INT Программное прерывание Команда hit инициирует в процессоре процедуру прерывания, в результате которой управление передается на обработчик прерывания с номером n, который указан в качестве операнда команды int. В стек текущей программы заносится содержимое регистра флагов, сегментного регистра CS и указателя команд IP, после чего в регистры IP и CS передается содержимое двух слов из вектора прерывания с номером n (расположенных по адресам 0:n*4 и 0:n*4+2). Команда сбрасывает флаги IF и TF в 0. Команда iret, которой всегда завершается обработчик прерывания, восстанавливает исходное состояние этих флагов. Пример 1 int 60h ;Переход на прикладной ;обработчик прерывания 60h Пример 2 mov AH,1 ;Функция MS-DOS - ввод с ;клавиатуры кода ASCII символа int 2h ;Вызов MS-DOS Пример 3 mov АН, 0 ;Функция BIOS (прерывание ;16h) - ввод с клавиатуры ;кода ASCII и скен-кода символа int 16h ;Вызов BIOS INTO Прерывание по переполнению Команда into, будучи установлена вслед за какой-либо арифметической, логической или строковой командой, вызывает обработчик прерываний через вектор 4, если предшествующая команда установила флаг переполнения OF. Перед использованием команды INTO прикладной программист должен поместить в вектор прерывания 4 двухсловный адрес своей программы обработки прерывания по переполнению. Команда сбрасывает флаги IF и TF в 0. Команда iret, которой всегда завершается обработчик прерывания, восстанавливает исходное состояние этих флагов. Пример add AX,BX ;Произвольная команда into ;Вызов прикладного ;обработчика через вектор 4, ;если OF=1 ... ;Продолжение программы, если OF=0 IRET Возврат из прерывания Команда iret возвращает управление прерванному в результате аппаратного или программного прерывания процессу. Команда извлекает из стека три верхние слова и помещает их в регистры IP, CS и флагов (см. команду int). Командой iret должен завершаться любой обработчик прерываний, как аппаратных, так и программных (от команды int). Команда не воздействует на флаги, однако она загружает в регистр флагов из стека его исходное содержимое, которое было там сохранено процессором в процессе обслуживания прерывания. Если требуется, чтобы после возврата из обработчика программного прерывания командой iret какие-либо флаги процессора были установлены требуемым образом (весьма распространенный прием), их установку надо выполнить в копии флагов в стеке. 386+ IRETD Возврат из прерывания в 32-разрядном режиме Команда iretd используется в защищенном режиме для возврата из обработчика прерывания или исключения, а также для переключения на исходную задачу. В отличие от 16-разрядной команды iret, данная команда, завершая обработку прерывания или исключения, снимает со стека 3 двойных слова, содержащие расширенный регистр флагов EFALGS, CS и расширенный указатель команд EIP. В случае переключения задач команда iretd выполняет переключение контекстов задач - сохранение состояния завершающейся задачи в ее сегменте состояния задачи и загрузку регистров процессора из сегмента состояния исходной задачи. Jcc Команды условных переходов Команды, обозначаемые (в книгах, не в программах!) Jcc, осуществляют переход по указанному адресу при выполнении условия, заданного мнемоникой команды. Если заданное условие не выполняется, переход не осуществляется, а выполняется команда, следующая за командой Jcc. Переход может осуществляться как вперед, так и назад в диапазоне + 127...-128 байтов. В составе команд процессора предусмотрены следующие команды условных переходов: Команда Перейти, если Условие перехода ja выше CF=0 и ZF=0 jae выше или равно CF=0 jb ниже CF=1 jbe ниже или равно CF=1 или ZF=1 jc перенос CF=1 jcxz CX=0 CX=0 je равно ZF=1 jg больше ZF=0 или SF=OF jge больше или равно SF=OF jl меньше SF не равно OF jle меньше или равно ZF=1 или SF не равно OF jna не выше CF=1 или ZF=1 jnae не выше и не равно CF=1 jnb не ниже CF=0 jnbe не ниже и не равно CF=0 и ZF=0 jnc нет переноса CF=0 jne не равно ZF=0 jng не больше ZF=1 или SF не равно OF jnge не больше и не равно SF не равно OF jnl не меньше SF=OF jnle не меньше и не равно ZF=0 и SF=OF jno нет переполнения OF=0 jnp нет четности PF=0 jns знаковый бит равен О SF=0 jnz не нуль ZF=0 jo переполнение OF=1 jp есть четность PF=1 jpe сумма битов четная PF=1 jpo сумма битов нечетная PF=0 js знаковый бит равен SF=1 jz нуль ZF= I Команды условных переходов, осуществляющие переход по условию "выше - ниже", предназначены для анализа чисел без знака; команды, осуществляющие переход по условию "больше - меньше", предназначены для анализа чисел со знаком. Пример 1 cmp СХ,0 ;CX=0? je equal ;Если да, перейти па метку equal Пример 2 cmp AX,1000 ;Пусть AX=8000h=32768 ;(=-32768) ja above ;32768 > 1000. Переход будет Пример 3 cmp AX,1000h ;Пусть AX=8000h=-32768 ; (=32768) jg greater ;-32768 < 1000h. Перехода не будет Пример 4 int 21h ;Вызов системной функции jc error ;Если CF=1 (ошибка), перейти ; на метку error Команды условных переходов имеют варианты 16- и 32-разрядной адресации (при тех же мнемонических обозначениях) и могут передавать управление в диапазоне -32768...+32767 байт для сегментов с атрибутом размера 16 и в диапазоне -231...+231-1 байт для сегментов с атрибутом размера 32. |
|
Создано: 26 февраля 2006 00:52 · Личное сообщение · #26 JMP Безусловный переход Команда jmp передает управление в указанную точку того же или другого программного сегмента. Адрес возврата не сохраняется. Команда не воздействует на флаги процессора. Команда jmp имеет пять разновидностей: - переход прямой короткий (в пределах -128... + 127 байтов); - переход прямой ближний (в пределах текущего программного сегмента) ; - переход прямой дальний (в другой программный сегмент); - переход косвенный ближний; - переход косвенный дальний. Все разновидности переходов имеют одну и ту же мнемонику jmp, хотя и различающиеся коды операций. Во многих случаях транслятор может определить вид перехода по контексту, в тех же случаях, когда это невозможно, следует использовать атрибутные операторы: short - прямой короткий переход; near ptr - прямой ближний переход; far ptr - прямой дальний переход; word ptr - косвенный ближний переход; dword ptr - косвенный дальний переход. Примеры прямого короткого перехода jmp short shpt ;Переход на метку shpt ;в пределах +127...-128 байтов jmp shpt ;To же самое, если shpt ;находится выше по тексту программы Примеры прямого ближнего перехода jmp pt ;Переход на метку pt ;в пределах текущего сегмента jmp near ptr pt ;To же самое Примеры косвенных ближних переходов Пример 1 mov BX,offset pt ;ВХ=адрес точки перехода jmp BX ;Переход в точку pt Пример 2 ;В полях данных: addr dw pt ;Ячейка с адресом точки перехода ;В программном сегменте: jmp DS:addr ;Переход в точку pt jmp word ptr addr ;To же самое Пример 3 ; В полях данных: addr dw pt ;Ячейка с адресом точки перехода ;В программном сегменте: mov DI,offset addr ;В1=адрес ячейки с адресом ;точки перехода jmp [DI] ;Переход в точку pt Пример 4 ;В полях данных: tbl dw ptl ;Ячейка с адресом 1 dw pt2 ;Ячейка с адресом 2 dw pt3 ;Ячейка с адресом 3 ;В программном сегменте: mov BX,offset tbl ;BX=aflpec таблицы адресов переходов mov SI, 4 ;31=смещение к адресу pt3 call [BX][SI] ;Переход в точку pt3 Примеры прямых дальних переходов jmp far ptr farpt ;Переход на метку farpt в ;другом программном сегменте jmp farpt ;Переход на метку farpt в другом ;программном сегменте, если farpt ;объявлена дальней меткой ;директивой farpt label far Примеры косвенных дальних переходов Пример 1 ; В полях данных: addr dd pt ;Поле с двухсловным ;адресом точки перехода ;В программном сегменте: jmp DS:addr ;Переход в точку pt jmp dword ptr addr ;To же самое Пример 2 ; В полях данных: addr dd pt ;Поле с двухсловным ;адресом точки перехода ;В программном сегменте: mov DI,offset addr ;DI =адрес поля с адресом ;точки перехода jmp [DI] ;Переход в точку pt Допустимо использование дополнительных режимов адресации 32-разрядных процессоров. Для 32-разрядных приложений допустимо использование 32-битовых операндов. В защищенном режиме вместо сегментного адреса сегмента (при дальних переходах) выступает его селектор. LAHF Загрузка флагов в регистр АН Команда lahf копирует флаги SF, ZF, AF, PF и CF соответственно в разряды 7, 6, 4, 2 и 0 регистра АН. Значение битов 5, 3 и 1 регистра АН не определено. Команда не имеет параметров и не изменяет флаги процессора. Команда lahf (совместно с командой sahf) дает возможность читать и изменять значения флагов процессора, в том числе флагов SF, ZF, AF и PF, которые нельзя изменить непосредственно. Однако следует иметь в виду, что команда lahf переносит в АН только младший байт регистра флагов. Поэтому нельзя изменить с ее помощью, например, состояние флага OF. Пример 1 lahf ;Регистр АН отображает ;состояние регистра флагов or AH,80h ;Установка бита 7 = SF sahf ;Загрузка АН в регистр ;флагов, где теперь SF = 1 Пример 2 lahf ;Регистр АН отображает ;состояние регистра флагов and AH,0BFh ;Сброс бита 6 = ZF sahf ;Загрузка АН в регистр ;флагов, где теперь ZF = О 386Р+ LAR Загрузка прав доступа Команда lar загружает в первый операнд (16- или 32-разрядный регистр) поле атрибутов сегмента из дескриптора сегмента, заданного селектором во втором операнде. В качестве операнда с селектором может использоваться 16- или 32-разрядный регистр или ячейка памяти. В операнд-приемник поступают два байта атрибутов селектора с замаскированным полем старших битов границы сегмента. LDS Загрузка указателя с использованием регистра DS Команда Ids считывает из памяти по указанному адресу двойное слово (32 бит), содержащее указатель (полный адрес некоторой ячейки), и загружает младшую половину указателя (т.е. относительный адрес) в указанный в команде регистр, а старшую половину указателя (т.е. сегментный адрес) в регистр DS. Таким образом, команда Ids reg, mem эквивалентна следующей группе команд: mov reg,word ptr mem mov DS,word ptr mem+2 В качестве первого операнда команды Ids указывается регистр общего назначения; в качестве второго - ячейка памяти с двухсловным содержимым. Указатель, содержащийся в этой ячейке, может быть адресом как процедуры, так и поля данных. Команда не воздействует на флаги процессора. Пример 1 ; В полях данных: addr dd myproc ;Двухсловный адрес процедуры ;myproc ;В программном сегменте: Ids SI,addr ;DS:SI -> myproc Пример 2 ; В полях данных: mem dw 25 ;Ячейка памяти с ; произвольным содержимым addr dd myproc ;Двухсловный адрес этой ;ячейки ;В программном сегменте: mov BX,offset addr ;ВХ=адрес ячейки addr Ids DX, [BX] ;DХ=смещение ячейки mem, ;DS=сегментный адрес ячейки ;mem Пример 3 ; В полях данных: dptr dd procl ;Полный адрес процедуры ; р г о с 1 dd proc2 ;Полный адрес процедуры ;ргос2 dd ргосЗ ;Полный адрес процедуры ; р г о с 3 ;В программном сегменте: mov SI, 8 ; Смещение к адресу ргосЗ Ids DI,dptr[SI] ;DSI ® ргосЗ Допустимо использование 32-разрядного регистра-приемника и 32-битового смещения в памяти, а также дополнительных режимов адресации 32-разрядных процессоров. В защищенном режиме вместо сегментного адреса сегмента выступает его селектор. LEA Загрузка исполнительного адреса Команда lea загружает в регистр, указанный в команде в качестве первого операнда, относительный адрес второго операнда (не значение операнда!). В качестве первого операнда следует указывать регистр общего назначения (не сегментный), в качестве второго - ячейку памяти. Команда lea reg,mem эквивалентна команде mov reg,offset mem но у первой команды больше возможностей описания адреса интересующей нас ячейки. Команда не воздействует на флаги процессора. Пример 1 ; В полях данных: message db ; 'Идут измерения' ;В программном сегменте: lea SI,message ;DS:SI -> message Пример 2 ; В полях данных: nmb db '0123456789' ;В программном сегменте: mov SI,7 ;Смещение символа '7' lea DX,nmb[SI] ;ВХ=адрес символа '7' Пример 3 ; В полях данных: nmb db '0123456789' ;В программном сегменте: mov BX, off set msg mov SI, 9 ;Смещение символа '9' lea SI, [BX] [SI] ;31=адрес символа '9' Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. 386+ LEAVE Выход из процедуры высокого уровня Команда leave выполняет действия, противоположные действиям последней команды enter. Она логически уничтожает созданный командой enter стековый кадр со всеми содержащимися в нем локальными переменными и подготавливает стек к выполнению команды irct, завершающей переход в вызывающую процедуру. Команда leave не имеет параметров. Более подробное описание и пример см. в описании команды enter. LES Загрузка указателя с использованием регистра ES Команда les считывает из памяти по указанному адресу двойное слово (32 бит), содержащее указатель (полный адрес некоторой ячейки), и загружает младшую половину указателя (т.е. относительный адрес) в указанный в команде регистр, а старшую половину указателя (т.е. сегментный адрес) в регистр ES. Таким образом, команда les reg,mem эквивалентна следующей группе команд: mov reg,word ptr mem mov ES,word ptr mem+2 В качестве первого операнда команды les указывается регистр общего назначения; в качестве второго - ячейка памяти с двухсловным содержимым. Указатель, содержащийся в этой ячейке, может быть адресом как процедуры, так и поля данных. Команда не воздействует на флаги процессора. Пример 1 ;В полях данных: addr dd myproc ;Двухсловный адрес процедуры ;myproc ;В программном сегменте: les SI,addr ;ES:SI ® myproc Пример 2 ;В полях данных: mem dw 25 ;Ячейка памяти с ;произвольным содержимым addr dd myproc ;Двухсловный адрес этой ячейки ;В программном сегменте: mov BX,offset addr ;ВХ=адрес ячейки addr … les DX, [BX] ; DХ=смещение ячейки mem, ;ЕS=сегментный адрес ячейки mem Пример 3 ;В полях данных: dptr dd procl ;Полный адрес процедуры prod dd proc2 ;Полный адрес процедуры ргос2 dd ргосЗ ;Полный адрес процедуры ргосЗ ;В программном сегменте: mov SI, 8 ;Смещение к адресу ргосЗ les DI,dptr[SI] ;ESI -> ргосЗ Допустимо использование 32-разрядного регистра-приемника и 32-битового смещения в памяти, а также дополнительных режимов адресации 32-разрядных процессоров. В защищенном режиме вместо сегментного адреса сегмента выступает его селектор. LFS Загрузка указателя с использованием регистра FS LGS Загрузка указателя с использованием регистра FS LSS Загрузка указателя с использованием регистра FS Команды считывают из памяти полный указатель, состоящий из селектора и 16-битового или 32-битового смещения, и загружают младшую половину указателя (т.е. относительный адрес) в указанный в команде регистр общего назначения, а старшую половину указателя (т.е. селектор) в сегментный регистр, указанный в мнемонике команды. В качестве первого операнда всех перечисленных команд указывается 16- или 32-разрядный регистр общего назначения; в качестве второго - ячейка памяти с 32- или 48-битовым содержимым. Команда не воздействует на флаги процессора. Примеры см. в описании команд Ids и les. |
|
Создано: 26 февраля 2006 00:53 · Личное сообщение · #27 86Р+ LGDT Загрузка регистра таблицы глобальных дескрипторов Команда Igdt загружает регистр таблицы глобальных дескрипторов (GDTR) из 48-битового псевдодескриптора, содержащего 32-битовый базовый адрес и 16-битовую границу таблицы глобальных дескрипторов, находящейся в памяти. В качестве операнда команды Igdt выступает относительный адрес псевдодескриптора. 386Р+ LIDT Загрузка регистра таблицы дескрипторов прерываний Команда lidt загружает регистр таблицы дескрипторов прерываний (IDTR) из 48-битового псевдодескриптора, содержащего 32-битовый базовый адрес и 16-битовую границу таблицы дескрипторов прерываний, находящейся в памяти. В качестве операнда команды lidt выступает относительный адрес псевдодескриптора. 386Р+ LLDT Загрузка регистра таблицы локальных дескрипторов Команда lldt загружает регистр таблицы локальных дескрипторов (LDTR) селектором, определяющим таблицу локальных дескрипторов (LDT). Селектор LDT должен входить в таблицу глобальных дескрипторов. В качестве операнда команды lldt, содержащего селектор LDT, можно использовать 16- или 32-разрядный регистр общего назначения или 16-или 32-битовое поле памяти. 386Р+ LMSW Загрузка слова состояния машины Команда Imsw загружает в регистр слова состояния машины (так называется младшая половина управляющего регистра процессора CRO) слово состояния машины, взятое из указанного в команде операнда. В качестве операнда можно использовать 16- или 32-разрядный регистр общего назначения или 16- или 32-битовое поле памяти. Команду Imsw можно использовать для перевода процессора из реального в защищенный режим или наоборот. В первом случае после чтения слова состояния командой smsw надо установить в нем бит 0 (бит РЕ) и загрузить назад в CRO командой Imsw. Во втором случае после после чтения слова состояния командой smsw надо сбросить в нем бит 0 и загрузить назад в CRO командой Imsw. LOCK Запирание шины Префикс lock, помещенный перед командой, устанавливает сигнал на линии LOCK системной шины и запрещает доступ к шине другим процессорам на время выполнения данной команды. Этот префикс предназначен для использования в многопроцессорных многозадачных системах для обеспечения исключительного доступа к памяти данного процесса (и данного процессора) на время проверки или модификации некоторой ячейки памяти. Типичный пример операций такого рода - работа с семафорами. Если два (или более) процесса, идущие на разных процессорах, используют какой-либо общий ресурс, например, файл или лазерный диск, то необходимо обеспечить механизм, запрещающий одновременное обращение процессов к общему ресурсу. Эта задача решается с помощью семафора - ячейки памяти (байта или даже бита), состояние которого отражает доступность или, наоборот, занятость ресурса. Если процессору понадобился общий ресурс, он читает состояние семафора и, если ресурс занят, продолжает опрашивать семафор до тех пор, пока другой процессор, использующий в настоящий момент общий ресурс, не освободит его. Обнаружив, что ресурс свободен, первый процессор устанавливает семафор в состояние "занят" и использует ресурс. Закончив работу с ресурсом, процессор сбрасывает его семафор и дает возможность другому процессу обратиться к тому же ресурсу. Описанный алгоритм будет работать только в том случае, если операция чтения- модификации- записи семафора будет выполняться в непрерываемом режиме. В противном случае оба процесса могут, одновременно обратившись к семафору, увидеть, что ресурс свободен, и начать его совместное использование. Избежать такой ситуации и позволяет префикс lock в сочетании с командами типа btr или bts, выполняющими комплексные операции проверки и сброса или проверки и установки бита. Будем считать, что семафор расположен в бите 0 байта по адресу sem, причем сброшенное состояние бита свидетельствует о занятости ресурса, а установленное состояние о том, что ресурс свободен. Тогда типичная процедура ожидания освобождения ресурса выглядит следующим образом: mov SI,offset sem ;Адрес байта с семафором getsem: lock btr byte ptr [SI],1 ;Проверка и сброс бита 0 jnc getsem Проверка состояния семафора и его модификация (запись в бит семафора 0, т.е. признака "занят") осуществляется в одной команде btr. На время выполнения этой команды шина многопроцессорной системы блокируется префиксом lock, и другой процессор обратиться к тому же семафору не может. Блокировка шины снимается уже после того, как семафор будет переведен в состояние занятости. Если при обращении к байту sem оказывается, что в битс семафора записан 0, т.е. ресурс занят другим процессом, команда btr сбрасывает флаг CF (путем переноса в него содержимого анализируемого бита), что приводит к многократному повторению процедуры getsem, т.е. к циклу ожидания освобождения ресурса. Типичная процедура освобождения занятого данным процессом ресурса выглядит следующим образом: freesem: lock bts byte ptr [SI],1 ;Проверка и установка бита 0 Собственно говоря, никакая проверка здесь не выполняется, однако процесс будет освобождать ресурс лишь если он этот ресурс использует, и проверять состояние флага в этой операции нет необходимости. Однако и здесь необходимо запирание шины на время записи в бит семафора 1, чтобы исключить одновременное обращение двух процессов к одной ячейке памяти. 386+ Префикс lock может быть использован только со следующими командами (и лишь при условии, что при их выполнении происходит обращение к памяти): adc, add, and, bt, bts, btr, btc, or, sbb, sub, xor, xchg, dec, inc, neg, not. LODS Загрузка операнда из строки LODSB Загрузка байта из строки LODSW Загрузка слова из строки Команды предназначены для операций над строками (строкой называется последовательность байтов или слов памяти с любым содержимым). Они загружают в регистр AL (в случае операций над байтами) или АХ (в случае операций над словами) содержимое ячейки памяти по адресу, находящемуся в паре регистров DS:SI. Команда lodsb загружает 1 байт, команда lodsw - 1 слово, а команда lods может быть использована для загрузки как байтов, так и слов. В последнем случае размер загружаемого данного определяется описанием строки (с помощью директив db или dw). После операции загрузки регистр SI получает положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1 или 2, в зависимости от размера загружаемого элемента. Команда не имеет параметров и не воздействует на флаги процессора. Вариант команды lods имеет формат lods строка (что не избавляет от необходимости инициализировать регистры DS:SI адресом строки). В этом формате возможна замена сегмента строки строка: lods ES:строка Пример 1 ;В полях данных сегмента данных, адресуемого через DS: str db 'qwertyuiop' ; В программном сегменте: сld ;Двигаемся по строке вперед mov SI, off set str ;Адрес строки add SI,BX ;Добавим смещение (пусть ВХ=4) lodsb ;AL='t', SI -> 'у' Пример 2 ;В полях данных сегмента данных, адресуемого через ES: str db 'qwertyuiop' ;В программном сегменте: сld ;Двигаемся по строке вперед mov SI,offset str ;Адрес строки lodsbES:str ;AL='q', ES:SI -> 'w' 386+ LODSD Загрузка двойного слова из строки Команда аналогична командам МП 86 lodb и lodsw, но позволяет загрузить из строки, адресуемой через регистры DS:ESI (DS:SI для 16-разрядных приложений), двойное слово в регистр ЕАХ. Пример ; В полях данных dat dd 12789,200000,550000,8000000 ;В программном сегменте mov SI,offset dat add SI, 4*3 ;DS:SI -> 4-й элемент массива чисел lodsd ;EAX=8000000 LOOP Циклическое выполнение, пока содержимое СХ не равно нулю Команда loop выполняет декремент содержимого регистра СХ, и если оно не равно 0, осуществляет переход на указанную метку вперед или назад в том же программном сегменте в диапазоне -128... + 127 байт. Обычно метка помещается перед первым предложением тела цикла, а команда loop является последней командой цикла. Содержимое регистра СХ рассматривается как целое число без знака, поэтому максимальное число повторений группы включенных в цикл команд составляет 65536 (если перед входом в цикл СХ=0). Команда не воздействует на флаги процессора. Пример 1 ;В полях данных: array dw 4096 dup (?) ;Массив из 4096 слов ;В программном сегменте: lea BX,array ;ВХ -> array xor SI,SI ;SI=0 mov CX,4096 ;Счетчик повторений mov AX,1 ;Число-заполнитель array: mov [BX] [SI],AX ;Очистка элемента массива inc SI ;Сдвиг к следующему inc SI ;слову массива loop array ;Повторить СХ раз Пример 2 mov CX,20 delay :loop delay ;Небольшая задержка При использовании в качестве счетчика расширенного регистра ЕСХ максимальное число шагов в цикле увеличивается до 232. Для того чтобы в 16-разрядном приложении процессор при выполнении команды loop использовал не 16-разрядный регистр СХ, а 32-разрядный регистр ЕСХ, перед командой loop необходимо указать префикс замены размера адреса 67h. Пример mov ЕСХ,О zzzz: db 67h ;Префикс замены размера адреса loop zzzz ;Цикл из 232: шагов, реализующий ;программную задержку порядка минут LOOPE/LOOPZ Циклическое выполнение, пока равно/циклическое выполнение, пока нуль Оба обозначения представляют собой синонимы и относятся к одной команде. Команда выполняет декремент содержимого регистра СХ, и если оно не равно 0, и флаг ZF установлен, осуществляет переход на указанную метку вперед или назад в том же программном сегменте в диапазоне -128...+127 байтов. Содержимое регистра СХ рассматривается как целое число без знака, поэтому максимальное число повторений группы включенных в цикл команд составляет 65536. Команда не воздействует на флаги процессора. Пример ;В полях данных, адресуемых через DS: command db 80 dup (' ') ;В программном сегменте: . . . ;Копирование в поле command строки, ;содержимое которой следует анализировать lea SI, command ;Настроим DS:SI сld ;Обработка вперед mov CX,80 ;Обрабатывать не более 80 ;байтов pass: lodsb ;Загрузим в AL очередной ;символ сmр АL, ' ' ;Пропустим все пробелы в loopepass ;начале строки dec SI ;Сдвиг на 1 символ назад ;DS:SI -> первый |
|
Создано: 26 февраля 2006 00:55 · Личное сообщение · #28 ;DS:SI -> первый символ, отличный от пробела При использовании в качестве счетчика расширенного регистра ЕСХ максимальное число шагов в цикле увеличивается до 232. Для того, чтобы в 16-разрядном приложении процессор при выполнении команд loope/loopz использовал не 16-разрядный регистр СХ, а 32-разрядный регистр ЕСХ, перед командами loope/loopz необходимо указать префикс замены размера адреса 67h. Пример mov ЕСХ, 1000000 ;Предельное число шагов хххх: ... ;Тело цикла db 67h loopexxxx LOOPNE/LOOPNZ Циклическое выполнение, пока не равно/циклическое выполнение, пока не нуль Оба обозначения представляют собой синонимы и относятся к одной команде. Команда выполняет декремент содержимого регистра СХ, и если оно не равно 0, и флаг ZF сброшен, осуществляет переход на указанную метку вперед или назад в том же программном сегменте в диапазоне -128... + 127 байтов. Содержимое регистра СХ рассматривается как целое число без знака, поэтому максимальное число повторений группы включенных в цикл команд составляет 65536. Команда не воздействует на флаги процессора. Пример ;В полях данных: command db 80 dup (0) ;В программном сегменте: . . . ;Копирование в поле command строки, ; содержимое которой следует анализировать lea SI,command ;Настроим DS:SI cld ;Обработка вперед mov CX,80 ;Обрабатывать не более 80 ;байтов slash: lodsb ;Загрузим в AL очередной символ cmp AL, ' / ' ;Ищем знак ' / ' loopne slash ;во всей строке ;DS:SI -> первый символ за знаком '/' При использовании в качестве счетчика расширенного регистра ЕСХ максимальное число шагов в цикле увеличивается до 232. Для того чтобы в 16-разрядном приложении процессор при выполнении команд loopne/loopnz использовал не 16-разрядный регистр СХ, а 32-разрядный регистр ЕСХ, перед командами loopne/loopnz необходимо указать префикс замены размера адреса 67h. Пример mov ЕСХ,1000000 ;Предельное число шагов хххх: . . . ;Тело цикла db 67h loopne xxxx 386Р+ LSL Загрузка границы сегмента Команда Isl загружает в первый операнд границу сегмента из дескриптора сегмента, заданного селектором во втором операнде. В качестве первого операнда команды Isl можно использовать 16- или 32-разрядный регистр общего назначения; в качестве второго - 16- или 32-разрядный регистр общего назначения или 16- или 32-битовое поле памяти. 386Р+ LTR Загрузка регистра задачи TR Команда Itr загружает регистр задачи TR селектором сегмента состояния задачи TSS из второго операнда, в качестве которого можно использовать 16- или 32-разрядный регистр общего назначения или 16- или 32-битовое поле памяти. Команда используется в защищенном режиме, если программный комплекс выполнен в виде нескольких самостоятельных задач, и переключения между ними осуществляются с использованием включенных в процессор аппаратных средств поддержки многозадачности. MOV Пересылка данных Команда mov замещает первый операнд (приемник) вторым (источником). При этом исходное значение первого операнда теряется. Второй операнд не изменяется. В зависимости от описания операндов, пересылается слово или байт. Если операнды описаны по-разному или режим адресации не позволяет однозначно определить размер операнда, для уточнения размера передаваемых данных в команду следует включить один из атрибутных операторов byte ptr или word ptr. Команда не воздействует на флаги процессора. В зависимости от используемых режимов адресации, команда mov может осуществлять пересылки следующих видов: - из регистра общего назначения в регистр общего назначения; - из регистра общего назначения в ячейку памяти; - из регистра общего назначения в сегментные регистры DS, ES и SS; - из ячейки памяти в регистр общего назначения; - из ячейки памяти в сегментный регистр; - из сегментного регистра в регистр общего назначения; - из сегментного регистра в ячейку памяти; - непосредственный операнд в регистр общего назначения; - непосредственный операнд в ячейку памяти. Запрещены пересылки из ячейки памяти в ячейку памяти (для этого предусмотрена команда movs), а также загрузка сегментного регистра непосредственным значением, которое, таким образом, приходится загружать через регистр общего назначения: mov AX,seg mem ;Сегментный адрес ячейки mem mov DS,AX ;Загрузка его в регистр DS Нельзя также непосредственно переслать содержимое одного сегментного регистра в другой. Такого рода операции удобно выполнять с использованием стека: push DS pop ES ; DS копируется в ES Примеры ;В полях данных: memb db 5,6 memd dd 0 ;Двухсловная ячейка ;В программном сегменте: mov DX,AX ;Из регистра в регистр mov AL,memb ;Из памяти в регистр mov AX,0B800h ;Непосредственное значение в ;регистр mov ES,AX ;Из регистра в сегментный ;регистр mov word ptr memd+2,ES ;Из сегментного ;регистра в память mov word ptr memd, 2000;Непосредственное ;значение в память mov BX,word ptr memb ;Слово из памяти в ;регистр (число 0605) mov DI,word ptr memd ;Слово из памяти в ;регистр mov ES,word ptr memd+2;Слово из памяти в ;сегментный регистр Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример 1 mov EAX,ESI Пример 2 ; В полях данных mem dd 0 ;В программном сегменте mov mem,EBP 386Р+ MOV Пересылка в\из специальных регистров Этот вариант команды mov (с той же мнемоникой, но другими кодами операций) используется в защищенном режиме и предназначен для обмена данными со специальными регистрами процессора: управляющими CRO...CR3, тестирования TR6 и TR7, а также регистрами отладки DRO...DR7. Один из операндов команды mov должен быть 32-разрядным регистром общего назначения, другим - один из специальных регистров процессора. MOVS Пересылка данных из строки в строку MOVSB Пересылка байта данных из строки в строку MOVSW Пересылка слова данных из строки в строку Команды предназначены для операций над строками (строкой называется последовательность байтов или слов памяти с любым содержимым). Они пересылают по одному элементу строки, который может быть байтом или словом. Первый операнд (приемник) адресуется через ESI, второй (источник) - через DS:SI. Операцию пересылки можно условно изобразить следующим образом: (DS:SI) -> (ESI) После каждой операции пересылки регистры SI и DI получают положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1 или 2 в зависимости от размера пересылаемых элементов. Вариант команды movs имеет формат: movs строка_1, строка_2 В этом случае байты или слова из строки строка_2 пересылаются на место строки строка_]. Размер пересылаемых элементов определяется описанием строк (с помощью директив db или dw). Это не избавляет от необходимости инициализировать регистры ESI и DS:SI адресами строк строка _1 и строка_2. В этом формате возможна замена сегмента второй строки (источника): movs строка_1, ES:строка_2 Рассматриваемые команды могут предваряться префиксом повторения rep (повторять СХ раз). После выполнения рассматриваемых команд регистры SI и DI указывают на ячейки памяти, находящиеся за теми (если DF=0) или перед теми (если DF=1) элементами строк, на которых закончились операции пересылки. Если флаг DF сброшен, то пары регистров DS:SI и ESI следует инициализировать начальными адресами строк-операндов; строка-источник будет пересылаться от се начала, в порядке возрастания номеров ее байтов. Если флаг DF установлен, то пары регистров DS:SI и ESI следует инициализировать конечными адресами строк-операндов; строка-источник будет пересылаться от ее конца, в порядке уменьшения номеров ее байтов. Команды не воздействует на флаги процессора. Пример 1 ;В полях данных основного сегмента данных, ;адресуемого через DS: txt db 'Урок 1' ;Пересылаемая строка txt_len equ S-txt ;Ee длина ;В 'полях данных дополнительного сегмента данных, ;адресуемого через ES : string db 80 dup (' ') ;В программном сегменте: lea SI,txt ;DS:SI -> txt lea DI,string+10.;ESI -> string+10 сld ;Движение по строке вперед mov CX,txt_len ;Столько байтов переслать rep movsb ;Пересылка Пример 2 ;В полях данных сегмента данных, адресуемого через DS: txt db 'А',84h, 'В',84h, 'A',84h, 'P', db 84h,'И',84h,'Я',84h,'!',84h txt_len=$-txt ;B программном сегменте: mov AX,0B800h ;Сегментный адрес видеобуфера mov ES,AX ;Инициализируем ES ;Выведем на экран текст mov DI,1672 ;Смещение к середине экрана lea SI,txt ;DS:SI ® txt сld ;Движение по строке вперед mov CX,txt_len/2 ;Столько слов переслать rep movsw ;Пересылка в середину экрана ;красной мерцающей (атрибут ;84h) надписи 'АВАРИЯ!' Пример 3 ;В полях данных сегмента данных, адресуемого через DS: datal dw 10000 dup(') ;Массив произвольных данных data2 dw 5000 dup(') ;Массив-приемник ;В программном сегменте push DS ;Настроим pop ES ;ES на тот же сегмент данных mov SI,offset datal;SI -> datal add SI,5000 ;Сместим SI к середине ;массива mov DI,offset data2;DI -> data2 mov CX,2500 ;Размер половины массива (в ;словах) сld ;Движение вперед rep movsw ;Перешлем вторую половину ;массива datal на место data2 Пример 4 ;В полях данных сегмента, адресуемого через DS file db 'MYFILE.01.DAT1,0 ;Строка-источник fname db 128 dup(?) ;Строка-приемник ;В программном сегменте push DS pop ES ;Теперь ES=DS mov SI,offset file;DS:SI -> strl mov SI,128 ;Максимальная длина имени ;файла сld ;Движение по строке вперед null: lodsb ;Загрузим в AL очередной ; символ cmp AL, 0 ;Ищем 0 в конце имени файла loopne null ;DS:SI ® Первый символ |
|
Создано: 26 февраля 2006 00:57 · Личное сообщение · #29 ;DS:SI ® Первый символ за концом имени файла (за ;завершающим нулем) dec SI ;SI -> байт с 0 std ;Движение по строке назад mov ВХ,128 ;Из начального значения СХ sub BX,CX ;вычтем то, что в СХ осталось mov СХ,ВХ ;СХ=число символов в имени (с 0) dec ВХ ;Смещение к 0 от начала имени файла lea DI,fname[ВХ] ;Смещение завершающего 0 rep movsb ;Перешлем все имя (от конца к началу) 386+ MOVSD Пересылка двойного слова из строки в строку Команда аналогична командам МП 86 movsb и movsw, но позволяет скопировать двойное слово из строки, адресуемой через регистры DS:ESI, в строку, адресуемую через регистры ES:EDI. Пример 1 ;В полях данных сегмента, адресуемого через DS strl db '01234567890ABCDEF' ;Строка-источник str2 db 16 dup(?) ;Строка-приемник ;B программном сегменте push DS pop ES ;Теперь ES=DS mov SI,offset strl ;DS:SI ®strl mov DI,offset str2 ;ESI -> str2 сld ;Движение по строке вперед mov CX,4 ;Коэффициент повторения rep movsd ;Копирование по 4*4 байт 386+ MOVSX Пересылка с расширением знака Команда пересылает байт в слово или двойное слово, а также слово в двойное слово с расширением знака. В качестве первого операнда (приемника) может использоваться 16- или 32-разрядный регистр общего назначения, в качестве второго - 8- или 16-разрядный регистр общего назначения или ячейка памяти такого же размера. Недопустима пересылка из памяти в память, в или из сегментного регистра, а также непосредственного значения. Фактически команда movsx увеличивает размер как положительного, так и отрицательного числа, ни изменяя ни его значения, ни знака. Пример 1 mov CL,-5 ;CL=FBh movsxAX,CL ;AX=FFFBh Пример 2 mov CL,+5 ;CL=05h movsxAX,CL ;AX=0005h Пример 3 mov BL,-128 ;BL=80h movsxECX,BL ;ECX=FFFFFF80h Пример 4 ; В полях данных mem dw -3 ;mem=FFFDh ;В программном сегменте movsxEB-X,mem ; EBX=FFFFFFFDh 386+ MOVZX Пересылка с расширением нуля Команда пересылает байт в слово или двойное слово, а также слово в двойное слово с заполнением старших разрядов нулями. В качестве первого операнда (приемника) может использоваться 16- или 32-разрядный регистр общего назначения, в качестве второго - 8- или 16-разрядный регистр общего назначения или ячейка памяти такого же размера. Недопустима пересылка из памяти в память, в или из сегментного регистра, а также непосредственного значения. Фактически команда movzx увеличивает размер числа, считая его числом без знака. Пример 1 mov CL,5 ;CL=05h movsxAX,CL ;AX=0005h Пример 2 mov CL,-5 ;CL=FBh movsxAX,CL ;AX=00FBh Пример 3 mov BL,80h ;BL=80h movsxECX,BL ;ECX=00000080h Пример 4 ;B полях данных mem dw 0FFFFh ;mem=FFFFh ;B программном сегменте movsxEBX,mem ;EBX=0000FFFFh MUL Умножение целых чисел без знака Команда inul выполняет умножение целого числа без знака, находящегося в регистре AL (в случае умножения на байт) или АХ (в случае умножения на слово), на операнд-источник (целое число без знака). Размер произведения в два раза больше размера сомножителей. Для однобайтовых операций один из сомножителей помещается в регистр AL; после выполнения операции произведение записывается в регистр АХ. Для двухбайтовых операций один из сомножителей помещается в регистр АХ; после выполнения операции произведение записывается в регистры DX:AX (в DX - старшая часть, в АХ - младшая). Предыдущее содержимое регистра DX затирается. Если содержимое регистра АН после однобайтового умножения или содержимое регистра DX после двухбайтового умножения не равны 0, флаги CF и OF устанавливаются в 1. В противном случае оба флага сбрасываются в 0. В качестве операнда-сомножителя команды mul можно указывать регистр (кроме сегментного) или ячейку памяти; не допускается умножение на непосредственное значение. Команда воздействует на флаги OF и CF. Пример 1 mov AL,5 ;Первый сомножитель mov BL,3 ;Второй сомножитель mul BL ;AX=000Fh, произведение Пример 2 mov AX,256 ;Первый сомножитель mov BX,256 ;Второй сомножитель mul BX ;DX=0001h, AX=0000h ;(DX:AX=65536, произведение) Пример 3 ;В полях данных coef db 100 ;Первый сомножитель datal db 126 ;Второй сомножитель mov AL,datal ;AL=7Eh=126 mul coef ;AX=3138h=12600,произведение Пример 4 ;B полях данных coef dw 5000 ;Первый сомножитель datal dw 1200 ;Второй сомножитель mov AX,datal ;AX=4BOh=1200 mul coef ;DX=005Bh, AX=8D80h ;Произведение=ВХ:AX= ;5B8D80h=6000000 Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. При этом, если указанный операнд представляет собой 32-байтовую величину, то результат размещается в регистрах EDX:EAX. Пример 1 mov EAX,200h ;Первый сомножитель mov ESI,l000000lh ;Второй сомножитель mul ESI ;Произведение в EDX:EAX ;EDX=00000020h,EAX=00000200h Пример 2 ; В полях данных nmbs db 15,22,36,78,84,98,100 ;В программном сегменте mov EDX,offset nmbs ;Относительный адрес movzx EDX,DX ;массива mov ECX,5 ;Смещение в массиве mov AL,10 ;Множитель mul byte ptr [EDX] [ЕСХ] ;Умножаем элемент ;массива с индексом 5 (98) ;на AL (10) Результат в ;АХ=980 NEG Изменение знака, дополнение до 2 Команда neg выполняет вычитание целочисленного операнда со знаком из нуля, превращая положительное число в отрицательное и наоборот. Исходный операнд затирается. В качестве операнда можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF. Пример 1 mov АХ,0 0 01 neg AX ;AX=FFFFh=-1 Пример 2 mov BX,-2 ;BX=FFFEh=-2 neg BX ;BX=0002h Пример 3 ;В полях данных nmb dw 800lh ;Если число со знаком, ;то -32767 ;В программном сегменте neg nmb ;nmb=7FFFh=+32767 Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример mov ECX, 5 neg ECX ;ECX=FFFFFFFBh=-5 NOP Холостая команда По команде пор процессор не выполняет никаких действий, кроме увеличения на 1 содержимого указателя команд IP (поскольку команда пор занимает 1 байт). Команда иногда используется в отладочных целях, чтобы "забить" какие-то ненужные команды, не изменяя длину загрузочного модуля или, наоборот, оставить место в загрузочном модуле для последующей вставки команд. В ряде случаев команды пор включаются в текст объектного модуля транслятором. Команда не имеет ни параметров, ни операндов и не воздействует на флаги процессора. NOT Инверсия, дополнение до 1, логическое отрицание Команда not выполняет инверсию битов указанного операнда, заменяя 0 на 1 и наоборот. В качестве операнда можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Команда не воздействует на флаги процессора. Правила побитовой инверсии: Операнд-бит 0 1 Бит результата 1 0 Пример 1 mov AX,0FFFFh not AX ;AX=0000h Пример 2 mov SI,5551h not SI ;SI=AAAEh Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример mov EAX,0C00SFF00h not EAX ;EAX=3FFC00FFh OR Логическое ВКЛЮЧАЮЩЕЕ ИЛИ Команда or выполняет операцию логического (побитового) сложения двух операндов. Результат замещает первый операнд (приемник); второй операнд (источник) не изменяется. В качестве первого операнда можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды команды or могут быть байтами или словами. Команда воздействует на флаги OF, SF, ZF, PF и CF, при этом флаги CF и OF всегда сбрасываются в 0. Правила побитового сложения: Первый операнд-бит 0101 Второй операнд-бит 0011 Бит результата 0111 Пример 1 mov AX,000Fh mov BX,00F0h or AX,BX ;AX=00FFh, BX=00F0h Пример 2 mov AX,000Fh mov BX,00F7h or AX,BX ;AX=00FFh, BX=00F7h Пример 3 mov AX,000Fh or AX,8001h ;AX=800Fh Пример 4 ; В полях данных mask db 80h ;B программном сегменте mov CH,17h or CH,mask ;CH=97h Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример ;В полях данных mem dd 80000000h ; В программном сегменте or mem,0C0h ;mem=800000C0h OUT Вывод в порт Команда out выводит в порт, указываемый первым операндом, байт или слово соответственно из регистра AL или АХ. Адрес порта помещается в регистр DX. Если адрес порта не превышает 255, он может быть указан непосредственным значением. Указание регистра-источника (AL или АХ) обязательно, хотя с другими регистрами команда out не работает, и их указывать нельзя. Команда не воздействует на флаги процессора. Пример 1 mov AL,20h ;Команда конца прерывания (EOI) out 20h,AL ;Вывод команды EOI в порт ;20h контроллера прерываний Пример 2 mov DX,3CEh ; Адрес порта mov AL,5 ;Данное out DX,AL ;Вывод байта из AL в порт 3CEh Допустимо использование в качестве операнда-источника расширенного регистра ЕАХ (если адресуемое устройство позволяет записать в его порт двойное слово). Пример mov ЕАХ,1А008РРЗh;Пересылаемое данное mov DX,345h ;Адрес порта out DX,EAX ;Вывод в порт двойного слова OUTS Вывод строки в порт OUTSB Вывод байта в порт OUTSW Вывод слова в порт OUTSD Вывод двойного слова в порт Команды предназначены для вывода данных в порт непосредственно из памяти. Адрес порта указывается, как и для команды out, в регистре DX, при этом задание адреса порта непосредственным значением не допускается. Данные извлекаются из памяти по адресу, находящемуся в паре регистров DS:ESI. Замена сегмента не допускается. Команда outsb передает в порт 1 байт, команда outsw - 1 слово, команда outsd - 1 двойное слово, а команда outs может быть использована для передачи байтов, слов и двойных слов. В последнем случ |
|
Создано: 26 февраля 2006 00:58 · Личное сообщение · #30 В последнем случае размер загружаемого данного определяется описанием строки (с помощью директив db, dw или dd). После передачи данных регистр ESI получает положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1, 2 или 4 в зависимости от размера передаваемых данных. Вариант команды outs имеет формат outs DX, строка (что не избавляет от необходимости инициализировать регистры DS:ESI адресом строки). Если устройство, адресуемое через порт, может принимать последовательность данных, то команды outs можно предварить префиксом повторения rep. В этом случае в порт пересылается СХ элементов данных заданного размера. Команды outs не воздействуют на флаги процессора. Пример 1 ; В полях данных mem dw 0FFh ;В программном сегменте mov SI, offset mem;ESI ® mem mov DX,303h ;Адрес порта outsb ;Вывод в порт 8-битового ;данного Пример 2 ; В полях данных string dw 0FFh,1,5,0Bh, 0 ; В программном сегменте mov SI, off set mem;ESI -> mem mov DX,340h Адрес порта mov CX, 5 ;Число данных eld ;Движение по данным вперед rep outsb ;Последовательный вывод в ;порт пяти 8-битовых данных POP Извлечение слова из стека Команда pop выталкивает 16-битовое данное из стека, т.е. пересылает слово из вершины стека (на которую указывает регистр SP) по адресу операнда-приемника. После этого содержимое SP увеличивается на 2, и SP указывает на предыдущее слово стека, которое теперь является его новой вершиной. Выталкивать из стека можно только целые слова (не байты). Программа должна строго следить за тем, чтобы каждой команде проталкивания в стек push отвечала обратная команда выталкивания из стека pop. Если стек используется для временного хранения некоторых данных, то извлекать эти данные из стека следует в порядке, обратном их сохранению. В качестве операнда-приемника можно использовать любой 16-разрядный регистр (кроме CS) или ячейку памяти. Команда не воздействует на флаги процессора. Пара команд push - pop часто используется для пересылки данного из регистра в регистр (особенно, в сегментный) через стек. Пример 1 push AX ;Временное сохранение push BX ;в стеке push DS ;трех операндов pop DS ;Восстановление из стека pop BX ;трех операндов pop AX ; в обратном порядке Пример 2 push CS ;Пересылка CS через стек pop DS ;Теперь DS=CS Пример 3 ;В полях данных mem dw 0 ; В программном сегменте pop mem ;Восстановление из стека в память Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Пример pop EAX ;Извлечение из стека двойного слова 386+ РОРА Восстановление из стека всех регистров Команда рора восстанавливает из стека содержимое всех регистров, предварительно сохраненных в стеке командой pusha. Заполнение из стека регистров осуществляется в следующем порядке: DI, SI, BP, SP, ВХ, DX, СХ, АХ. Исходное содержимое указателя стека SP, сохраненное в стеке командой pusha, командой рора из стека извлекается, но отбрасывается. Команда не имеет параметров. Пример рора 386+ POPAD Восстановление из стека всех регистров в 32-разрядном режиме Команда popad восстанавливает из стека содержимое всех расширенных регистров, предварительно сохраненных в стеке командой pushad. Заполнение из стека регистров осуществляется в следующем порядке: EDI, ESI, EBP, ESP, ЕВХ, EDX, ЕСХ, ЕАХ. Исходное содержимое указателя стека ESP, сохраненное в стеке командой pusha, командой рора из стека извлекается, но отбрасывается. Команда не имеет параметров. Пример popad POPF Восстановление из стека регистра флагов Команда popf пересылает верхнее слово стека (на которое указывает регистр SP) в регистр флагов FLAGS. После этого содержимое SP увеличивается на 2, и SP указывает на предыдущее слово стека, которое теперь является его новой вершиной. Команда popf не имеет параметров; она воздействует на все флаги процессора, кроме флагов VM и RF. Пример 1 popf ;Регистр флагов загружается из стека Пример 2 pushf ;Отправим флаги в стек mov BP,SP ;Настроим ВР на флаги в стеке or [BP],100h ;Установим бит 100h (флаг TF) popf ;Вытолкнем в регистр флагов. ;Теперь в регистре флагов TF=1 386+ POPFD Восстановление из стека расширенного регистра флагов Команда popfd пересылает верхнее слово стека (на которое указывает регистр ESP) в расширенный регистр флагов EFLAGS. После этого содержимое ESP увеличивается на 4, и ESP указывает на предыдущее слово стека, которое теперь является его новой вершиной. Команда popfd не имеет параметров; она воздействует на все флаги процессора. Пример popfd ;Регистр EFLGS загружается из стека PUSH Занесение операнда в стек Команда push уменьшает на 2 содержимое указателя стека SP и заносит на эту новую вершину двухбайтовый операнд-источник (проталкивает в стек новое данное). Проталкивать в стек можно только целые слова (не байты). Программа должна строго следить за тем, чтобы каждой команде проталкивания в стек push отвечала обратная команда выталкивания из стека pop. Если стек используется для временного хранения некоторых данных, то извлекать эти данные из стека следует в порядке, обратном их сохранению. В качестве операнда-источника может использоваться любой 16-разрядный регистр (включая сегментный) или ячейка памяти. Не допускается занесение в стек непосредственного значения, хотя некоторые трансляторы преобразуют команду вида push 1234h в неэффективную последовательность операций со стеком, результатом которой будет проталкивание указанного операнда в стек. Команда push не воздействует на флаги процессора. Пара команд push - pop часто используется для пересылки данного из регистра в регистр (особенно, в сегментный) через стек. Пример 1 push ES:mem ;Сохранение содержимого push DS ;слова памяти mem из push BP ;дополнительного сегмента ;а также регистров DS и ВР … ; pop PP ;Восстановление из стека pop DS ;трех операндов pop ES: mem ;в обратном порядке Пример 2 push DS ;Пересылка DS через стек pop ES ;Теперь ES=DS Допустима засылка в стек 32-битовых операндов (регистров и ячеек памяти), а также занесение в стек 8-, 16- и 32-битовых непосредственных значений. Каждое 8-битовое значение занимает в стеке целое слово. Операнды любого допустимого размера могут заноситься з стек вперемежку', если это не вступает в противоречие с операциями по извлечению этих данных из стека. Пример 1 push AX ; Сохранение в стеке регистра АХ push 32h ;Сохранение в стеке ;константы 32h (она займет в ;стеке 1 слово) push EAX ;Сохранение в стеке регистра ;ЕАХ (два слова стека) 386+ PUSHA Сохранение в стеке всех регистров Команда pusha сохраняет в стеке содержимое всех регистров в следующем порядке: АХ, СХ, DX, ВХ, значение указателя стека SP перед выполнением данной команды, дачее ВР, SI и DI. Команда не имеет параметров и не воздействует на флаги процессора. Пример pusha 386+ PUSHAD Сохранение в стеке всех регистров в 32-разрядном режиме Команда pushad сохраняет в стеке содержимое всех регистров в следующем порядке: EAX, ECX, EDX, ЕВХ, значение указателя стека ESP перед выполнением данной команды, далее EBP, ESI и EDI. Команда не имеет параметров и не воздействует на флаги процессора. Пример pushad 386+ PUSHFD Занесение в стек содержимого расширенного регистра флагов Команда pushfd уменьшает на 4 содержимое указателя стека ESP и заносит на эту новую вершину содержимое расширенного регистра флагов EFALGS. При этом сохраняются все флаги процессора. Команда pushfd не имеет параметров и не воздействует на флаги процессора. Пример pushfd ;Содержимое регистра флагов ;сохраняется в стеке RCL Циклический сдвиг влево через бит переноса Команда гсl осуществляет сдвиг влево всех битов операнда. Если команда записана в формате rcl операнд,1 сдвиг осуществляется на 1 бит. В младший бит операнда заносится значение флага CF; старший бит операнда загружается в CF. Если команда записана в формате rcl операнд,CL сдвиг осуществляется на число бит, указанное в регистре-счетчике CL, при этом в процессе последовательных сдвигов старшие биты операнда поступают сначала в CF, а оттуда - в младшие биты операнда (рис. П4). Рис. П4. Действие команды rcl. В качестве операнда команды rcl можно указывать любой регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Команда воздействует на флаги OF и CF. Пример 1 clc ;Сбросим CF mov AX, 7 rcl АХ,1 ' ;AX=000Eh=14, CF=0 Пример 2 stc ;Установим CF mov DL,7 rcl DL,1 ;DL=0Fh=15, CF=0 Пример 3 clc ;Сбросим CF mov BX,0FFFFh rcl BX,1 ' ;BX=FFFEh, CF=1 Пример 4 clc ;Сбросим CF mov DH,3 mov CL,4 ;Счетчик сдвигов rcl DH,CL ;DH=30h=48, CF=0 Допустим сдвиг 32-битовых операндов. Допустимо указание числа битов сдвига как с помощью регистра CL, так и непосредственным значением. Максимальная величина сдвига составляет 31 бит. Пример mov EAX,0С0000003h clc ;Сбросим CF rcl EAX,2 ;EAX=0000000Dh, CF=1 |
. 1 . 2 . >> |
eXeL@B —› Вопросы новичков —› Справочник по командам ассемблера |