Инструкции процессоров Intel
Помощь студентам. Курсовые, дипломы, чертежи (КОМПАС), задачи по программированию: Pascal/Delphi/Lazarus; С/С++; Ассемблер; языки программирования ПЛК; JavaScript; VBScript; Fortran; Python и др. Разработка (доработка) ПО ПЛК (предпочтение — ОВЕН, CoDeSys 2 и 3), а также программирование панелей оператора, программируемых реле и других приборов систем автоматизации. Подробнее.
Как известно, программирование на Ассемблере — это написание исходных текстов, которые представляют собой набор команд (инструкций) процессора. В этом разделе публикуются подробные описания инструкций процессоров Интел и совместимых.
- AAA
- AAD
- AAM
- AAS
- ADC
- ADD
- AND
- CALL
- CBW
- CLC
- CLD
- CLI
- CMC
- CMP
- CMPSB
- CMPSW
- CWD
- DEC
- DIV
- JB
- JBE
- JE
- JG
- JGE
- JL
- JLE
- JMP
- JNA
- JNB
- JNL
- INC
- LEA
- LDS
- LES
- LOOP
- MOV
- MUL
- NEG
- NOP
- NOT
- OR
- OUT
- RCL
- RCR
- RET
- SBB
- STC
- STD
- STOSB
- SUB
- TEST
- XCHG
- XLATB
- XOR
Я уже не раз об этом говорил, но снова повторю — вдруг кто не слышал )))
Каждый процессор имеет свой набор команд (инструкций)!
Поэтому, если вы изучите инструкции одного процессора, то это не значит, что вы легко сможете создавать программы на языке Ассемблера. Потому что язык Ассемблера одинаков для всех процессоров (ну почти одинаков). Однако инструкции, используемые в языке Ассемблера, могут быть (и так оно и есть) отличаться в зависимости от того, для какого процессора вы пишите программу.
Кроме того, команды с одинаковым именем могут по разному работать с разными процессорами.
Тем не менее, изучать то язык как-то надо. Поэтому обычно начинают с каких-то основ. Как правило, с изучения основных инструкций, которые очень похожи для большинства процессоров (и микроконтроллеров в том числе).
Набор базовых команд процессора
Именно с базовых инструкций лучше всего начать изучать Ассемблер. Такими базовыми командами (инструкциями) являются команды сложения, вычитания и других простых математических операций. А также команды перемещения значения из одного источника в другой (например, из области памяти в регистр).
Пример инструкций процессора Интел (8086): ADD (сложение), SUB (вычитание), MOV (перемещение) и т.п.
Базовым набором команд процессора Intel можно считать полный набор инструкций процессора 8086, у которого было 116 команд. У современных процессоров команд, конечно, намного больше (хотя это зависит от архитектуры — есть процессоры с сокращённым набором команд, где их всего несколько десятков).
Современные процессоры кроме основных команд имеют ещё и разные расширения, такие как набор команд MMX, которые предназначены для более быстрого выполнения определённых операций.
Вообще это тема очень объёмная и довольно сложная. Поэтому в очередной раз советую вам изучить (причём очень тщательно) какую-нибудь хорошую книгу по Ассемблеру (на этом сайте есть ссылки на такие книги).
Ну а я на этом краткий обзор закончу. Смотрите содержание раздела выше. Описания новых инструкций будут периодически добавляться по мере создания материала. Так что подписывайтесь на новости сайта, чтобы всегда быть в курсе последних событий.
MS-DOS и TASM 2.0. Часть 10. Команды ассемблера.
Команды ассемблера и команды процессора.
Стоит пояснить, что если к вопросу подойти формально строго, то команды процессора и команды ассемблера — это не одно и то же. Ассеммблер — хоть и низкоуровневый язык программирования, но иногда он без спроса программиста «корректирует код под себя». Причём у каждого ассемблера (masm, tasm, fasm) это может быть по-разному. Самый яркий пример — команда ret. В ассемблерном коде мы запишем ret, а реальный ассемблер ассемблирует её как retf или retn 8. Может также изменяться код, добавлением в качестве выравнивания кода команды процессора nop (об этом ниже в статье) и т.п. Чтобы не усложнять суть вопроса, под понятиями команды процессора и команды ассемблера мы будем подразумевать одно и то же.
Команды процессора (команды ассемблера) в большинстве своём работают с аргументами, которые в ассемблере называются операндами. Система машинного кода процессоров Intel содержит более 300 команд (команды процессора, сопроцессора, MMX-расширения, XMM-расширения). С каждым новым процессором их количество растёт. Для того, чтобы профессионально программировать, не надо зубрить и разбирать все команды процессора. При необходимости можно воспользоваться справочником. В процессе чтения статей, вы поймёте, что основная суть знания ассемблера состоит не в доскональном знании всех команд, а в понимании работы системы.
Не следует забывать, что команды процессор видит в виде цифр, которые можно рассматривать как данные. Например, команда NOP занимает один байт и её машинный код — 90h.
Начиная изучать язык низкого уровня, мы будем иметь дело с ограниченным набором старых-добрых команд процессора. Иные команды ассемблера понадобятся специалистам, заинтересованным в оптимизацией кода, связанного со сложными математическими расчетами данных большого объёма.
Основные (т.н. целочисленные) команды ассемблера позволяют написать практически любую программу для операционных систем MS-DOS и Windows. Количество команд ассемблера, которыми вы будете пользоваться будет расти со временем прохождения курса. Для более детального понимания, в последствии можете обратиться к справочнику команд.
Рассмотрим команды ассемблера на практическом примере.
С использованием среды разработки TASMED или любого текстового редактора набираем код. Программа, задаст вопрос на английском языке о половой принадлежности (имеется ввиду ваш биологический пол при рождении). Если вы нажмете m (Man), будет выведено приветствие с мужчиной, если w (Woman), то с женщиной, после этого программа прекратит работу. Если будет нажата любая другая клавиша, то программа предположит, что имеет дело с гоблином, не поверит и будет задавать вам вопросы о половой принадлежности, пока вы не ответите верно.
Базовая система команд микропроцессора
Базовую систему команд микропроцессора можно условно разделить на несколько групп по функциональному назначению:
Кроме базовой системы команд микропроцессора существуют также команды расширений:
- X87 – расширение, содержащее команды математического сопроцессора (работа с вещественными числами)
- MMX – расширение, содержащее команды для кодирования/декодирования потоковых аудио/видео данных;
- SSE – расширение включает в себя набор инструкций, который производит операции со скалярными и упакованными типами данных;
- SSE2 – модификация SSE, содержит инструкции для потоковой обработки целочисленных данных, что делает это расширение более предпочтительным для целочисленных вычислений, нежели использование набора инструкций MMX, появившегося гораздо раньше;
- SSE3, SSE4 – содержат дополнительные инструкции расширения SSE.
В таблице команд приняты следующие обозначения:
r – регистр
m – ячейка памяти
c – константа
8, 16, 32 – размер в битах
На все базовые команды процессора накладываются следующие ограничения:
- Нельзя в одной команде оперировать двумя областями памяти одновременно. Если такая необходимость возникает, то нужно использовать в качестве промежуточного буфера любой доступный в данный момент регистр общего назначения.
- Нельзя оперировать сегментным регистром и значением непосредственно из памяти. Поэтому для выполнения такой операции нужно использовать промежуточный объект. Это может быть регистр общего назначения или стек.
- Нельзя оперировать двумя сегментными регистрами. Это объясняется тем, что в системе команд нет соответствующего кода операции. Но необходимость в таком действии часто возникает. Выполнить такую пересылку можно, используя в качестве промежуточных регистры общего назначения. Например,
Команды передачи данных
Основной командой передачи данных является команда MOV , осуществляющая операцию присваивания:
Команда MOV присваивает значению операнда приемника значение операнда источника. В качестве приемника могут выступать регистр общего назначения, сегментный регистр или ячейка памяти, в качестве источника могут выступать константа, регистр общего назначения, сегментный регистр или ячейка памяти. Оба операнда должны быть одного размера.
Команды передачи данных представлены в таблице.
Команда | Операнды | Пояснение | Описание |
MOV | r(m)8,r8 r(m)16,r16 r(m)32,r32 r8,r(m)8 r16,r(m)16 r32,r(m)32 r(m)8,c8 r(m)16,c16 r(m)32,c32 | r(m)8=r8 r(m)16=r16 r(m)32=r32 r8=r(m)8 r16=r(m)16 r32=r(m)32 r(m)8=с8 r(m)16=с16 r(m)32=с32 | Пересылка операндов |
XCHG | r(m)8, r8 r8, r(m)8 r(m)16,r16 r16, r(m)16 r(m)32, r32 r32, r(m)32 | r(m)8 ↔r8 r8 ↔r(m)8 r(m)16↔r16 r16 ↔r(m)16 r(m)32↔r32 r32 ↔r(m)32 | Обмен операндов |
BSWAP | r32 | TEMP ← r32 r32[7..0]←TEMP[31..24] r32[15..8]←TEMP[23..16] r32[23..16]←TEMP[15..8] r32[31..24]←TEMP[7..0] | Перестановка байтов из порядка «младший – старший» в порядок «старший – младший» |
MOVSX | r16, r(m)8 r32, r(m)8 r32, r(m)16 | r16,r(m)8 DW ← DB r32,r(m)8 DD ← DB r32,r(m)16 DD ← DW | Пересылка с расширением формата и дублированием знакового бита |
MOVZX | r16,r(m)8 r32,r/m8 r32,r/m16 | r16,r(m)8 DW ← DB r32,r(m)8 DD ← DB r32,r(m)16 DD ← DW | Пересылка с расширением формата и дублированием нулевого бита |
XLATXLATB | m8 | AL=DS:[(E)BX+unsigned AL] | Загрузить в AL байт из таблицы в сегменте данных, на начало которой указывает EBX (ВХ); начальное значение AL играет роль смещения |
LEA | r16, m r32, m | r16=offset m r32=offset m | Загрузка эффективного адреса |
LDS | r16,m16 r32,m16 | DS:r=offset m | Загрузить пару регистров из памяти |
LSS | SS:r=offset m | ||
LES | ES:r=offset m | ||
LFS | FS:r=offset m | ||
LGS | GS:r=offset m |
Команды установки единичного бита
Проверяют условие состояния битов регистра EFLAGS и, если условие выполняется, то младший бит операнда устанавливается в 1, в противном случае в 0. Анализ битов производится аналогично условным переходам.
Команда | Операнды | Пояснение |
SETA SETNBE | r(m)8 | CF=0 и ZF=0 |
SETAE SETNB SETNC | CF=0 | |
SETB SETC SETNAE | CF=1 | |
SETBE SETNA | CF=1 или ZF=1 | |
SETE SETZ | ZF=1 | |
SETG SETNLE | ZF=0 и SF=OF | |
SETGE SETNL | SF=OF | |
SETL SETNGE | SF!=OF | |
SETLE SETNG | SF!=OF или ZF=1 | |
SETNE SETNZ | ZF=0 | |
SETNO | OF=0 | |
SETNP SETPO | PF=0 | |
SETNS | SF=0 | |
SETO | OF=1 | |
SETP SETPE | PF=1 | |
SETS | SF=1 |
Команды работы со стеком
Команда | Операнды | Пояснение | Описание |
PUSH | r(m)32 r(m)16 c32 | ESP=ESP-4; SS:ESP=r(m)32/c SP=SP-2; SS:SP=r(m)16 | Поместить операнд в вершину стека |
POP | r(m)32 r(m)16 | r(m)32=SS:ESP; ESP=ESP+4 r(m)16=SS:SP; SP=SP+2; | Извлечь операнд из вершины стека |
PUSHA PUSHAD | r(m)32 r(m)16 | — | Поместить в стек регистры EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP |
POPA POPAD | — | Извлечь из стека содержимое и заполнить регистры EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP | |
PUSHF | — | Поместить в вершину стека регистр EFLAGS | |
POPF | — | Извлечь содержимое вершины стека и заполнить регистр EFLAGS |
Команды ввода-вывода
Микропроцессор может передавать данные в порты ввода-вывода, которые поддерживаются аппаратно и используют соответствующие своим предназначениям линии ввода-вывода процессора. Аппаратное адресное пространство ввода-вывода процессора не является физическим адресным пространством памяти. Адресное пространство ввода-вывода состоит из 64Кбайт индивидуально адресуемых 8-битных портов ввода-вывода, имеющих адреса 0…FFFFh. Адреса 0F8h…0FFh являются резервными. Любые два последовательных 8-битных порта могут быть объединены в 16-битный порт, 4 последовательных 8-битных порта – в 32-битный порт.
Команда | Операнды | Пояснение | Описание |
IN | AL,c8 AX,c8 EAX,c8 AL,DX AX,DX EAX,DX | AL= port byte AX= port word EAX= port dword AL= [DX-port] AX= [DX-port] EAX= [DX-port] | Ввод из порта |
OUT | c8, AL c8, AX c8, EAX DX, AL DX, AX DX, EAX | port byte=AL port word=AX port dword=EAX [DX-port]=AL [DX-port]=AX [DX-port]=EAX | Вывод в порт |
INSB INSW INSD | — | ES:(E)DI = [DX-port] | Вводит данные из порта, адресуемого DX в ячейку памяти ES:[(E)DI]. После ввода 1, 2 или 4-байтного слова данных EDI/DI корректируется на 1,2,4. При наличии префикса REP процесс продолжается, пока EСХ>0 |
OUTSB OUTSW OUTSD | — | [DX-port]=DS:(E)SI | Выводит данные из ячейки памяти, определяемой регистрами DS:[(E)SI], в порт, адрес которого находится в DX. После вывода данных производится коррекция указателя ESI/SI на 1,2 или 4 |
Команды целочисленной арифметики
Команда | Операнды | Пояснение | Описание |
ADD | r(m)8,с8 r(m)16,с16 r(m)32,с32 r(m)8,r8 r(m)16,r16 r(m)32,r32 r8,r(m)8 r16,r(m)16 r32,r(m)32 | r(m)8=r(m)8+с8 r(m)16=r(m)16+с16 r(m)32=r(m)32+c32 r(m)8=r(m)8+r8 r(m)16=r(m)16+r16 r(m)32=r(m)32+r32 r8=r8+r(m)8 r16=r16+r(m)16 r32=r32+r(m)32 | Сложение целых чисел |
ADC | Сложение целых чисел с учетом флага переноса CF | ||
INC | r(m)8 r(m)16 r(m)32 | r/m8=r/m8±1 r(m)16=r(m)16±1 r(m)32=r(m)32±1 | Увеличение на 1 |
DEC | Уменьшение на 1 | ||
SUB | r(m)8,с8 r(m)16,с16 r(m)32,с32 r(m)8,r8 r(m)16,r16 r(m)32,r32 r8,r(m)8 r16,r(m)16 r32,r(m)32 | r(m)8=r(m)8-с8 r(m)16=r(m)16-с16 r(m)32=r(m)32-c32 r(m)8=r(m)8-r8 r(m)16=r(m)16-r16 r(m)32=r(m)32-r32 r8=r8-r(m)8 r16=r16-r(m)16 r32=r32-r(m)32 | Вычитание целых чисел |
SBB | Вычитание с учетом флага переноса CF | ||
CMP | r(m)8,с8 r(m)16,с16 r(m)32,с32 r(m)8,r8 r(m)16,r16 r(m)32,r32 r8,r(m)8 r16,r(m)16 r32,r(m)32 | r(m)8-с8 r(m)16-с16 r(m)32-c32 r(m)8-r8 r(m)16-r16 r(m)32-r32 r8-r(m)8 r16-r(m)16 r32-r(m)32 | Сравнение целых чисел По результату сравнения устанавливаются флаги CF PF AF ZF SF OF |
NEG | r(m)8 r(m)16 r(m)32 | r(m)8=-r(m)8 r(m)16=-r(m)16 r(m)32=-r(m)32 | Изменение знака числа |
MUL | r(m)8 r(m)16 r(m)32 | AX=AL*r(m)8 DX:AX=AX*r(m)16 EDX:EAX=EAX*r(m)32 | Умножение без знака |
IMUL | r(m)8 r(m)16 r(m)32 r16,r(m)16 r32,r(m)32 r16,r(m)16,c r32,r(m)32,c r16,c r32,c | AX=AL*r(m)8 DX:AX=AX*r(m)16 EDX:EAX=EAX*r(m)32 r16=r16*r(m)16 r32=r32*r(m)32 r16=r(m)16*c16 r32=r(m)32*c32 r16=r16*c16 r32=r32*c32 | Умножение со знаком |
DIV | r(m)8 r(m)16 r(m)32 | AL=AX/r(m)8, AH=mod AX=DX:AX/r(m)16, DX=mod EAX=EDX:EAX/r(m)32, EDX=mod | Деление без знака |
IDIV | Деление со знаком |
Особого внимания среди рассмотренных команд целочисленной арифметики заслуживает команда CMP , которая вычитает второй операнд из первого и не сохраняет результат, а устанавливает биты OF, SF, ZF, AF, PF, CF регистра признаков EFLAGS в соответствии с результатом. Команда CMP чаще всего предшествует командам знакового или беззнакового условных переходов.
Логические команды
Выполнение логических операций описано здесь
Команда | Операнды | Пояснение | Описание |
AND | r(m)8,с8 r(m)16,с16 r(m)32,с32 r(m)8,r8 r(m)16,r16 r(m)32,r32 r8,r(m)8 r16,r(m)16 r32,r(m)32 | r(m)8=r(m)8 Ф с8 r(m)16=r(m)16 Ф с16 r(m)32=r(m)32 Ф c32 r(m)8=r(m)8 Ф r8 r(m)16=r(m)16 Ф r16 r(m)32=r(m)32 Ф r32 r8=r8 Ф r(m)8 r16=r16 Ф r(m)16 r32=r32 Ф r(m)32 | Логическое умножение (И), конъюнкция |
OR | Логическое сложение (ИЛИ), дизъюнкция | ||
XOR | Исключающее ИЛИ | ||
NOT | r(m)8 r(m)16 r(m)32 | r(m)8= |
r(m)32
r(m)16,с16
r(m)32,с32
r(m)8,r8
r(m)16,r16
r(m)32,r32
r8,r(m)8
r16,r(m)16
r32,r(m)32
r(m)16 & с16
r(m)32 & с32
r(m)8 & r8
r(m)16 & r16
r(m)32 & r32
r8 & r(m)8
r16 & r(m)16
r32 & r(m)32
PF ZF SF
Сдвиговые команды
Выполнение сдвиговых операций в языке Си рассмотрено здесь .
Команда | Операнды | Пояснение | Описание |
SHR | r(m)8 r(m)8,CL r(m)8,с r(m)16 r(m)16,CL r(m)16,c r(m)32 r(m)32,CL r(m)32,c | r(m)8 на 1 раздяд r(m)8 на CL разрядов r(m)8 на с разрядов r(m)16 на 1 разряд r(m)16 на CL разрядов r(m)16 на c разрядов r(m)32 на 1 разряд r(m)32 на CL разрядов r(m)32 на c разрядов | Логический сдвиг вправо |
SAR | Арифметический сдвиг вправо (старшие разряды заполняются значением знакового) | ||
SHL SAL | Логический (арифметический) сдвиг влево | ||
ROR | Циклический сдвиг вправо | ||
ROL | Циклический сдвиг влево | ||
RСR | Циклический сдвиг вправо через перенос | ||
RCL | Циклический сдвиг влево через перенос |
Команды циклического сдвига выполняются в соответствии со схемой
Команды коррекции двично-десятичных чисел
Команды коррекции двоично-десятичных чисел не имеют операндов и используют операнд по умолчанию, хранящийся в регистре AX (паре регистров AH:AL ).