
- •2) Инкремент любого регистра (8- или 16-разрядного), байта или слова памяти. Код команды занимает два байта (старший байт носит название постбайта):
- •2А) Операнд в регистре. Таблицу кодирования регистров придется расширить.
- •7.2. Двухоперандные команды.
- •7.3. Непосредственный операнд.
- •2) Что короче: mov bx,0 или sub bx,bx ?
7.3. Непосредственный операнд.
Напомним, что удобство использования непосредственного операнда определяется двумя причинами: 1) уменьшается требуемая память (иначе пришлось бы в команде хранить адрес константы, а саму константу хранить в памяти), 2) непосредственный операнд берется прямо из кода команды, поэтому не тратится время на обращение к памяти для выборки операнда.
Опять обратимся к примеру. Команда сложения с непосредственным операндом максимально кодируется шестью байтами.
|
|
постбайт |
|
|
|
|
|
|
|
|
|
|
|
|
DISP-LO |
|
DISP-HI |
|
DATA-LO |
|
DATA-HI |
|
|
|
|
присутствие зависит от поля mod |
|
|
|
имеется, если s:w=01 |
Байты, которые необязательно присутствуют в коде команды, показаны пунктиром.
Сначала посмотрим структуру первых двух байтов:
1 |
0 |
0 |
0 |
0 |
0 |
|
|
|
|
|
0 |
0 |
0 |
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
КОП |
s |
w |
|
mod |
КОП |
r/m |
Сразу заметим, что код операции ADD изменился, увеличилась и его длина: вместо 6 бит стало 9. Бит приемника d исчез — понятно почему, ведь непосредственный операнд не может быть приемником. Поля mod и r/m нам уже знакомы. Соответственно, в зависимости от mod в коде может присутствовать смещение D8 или D16.
Зато появился новый бит s (sign — знак). Он занимает место d, так как бит d теперь не нужен. Смысл бита s таков. В арифметических операциях часто используются небольшие по величине непосредственные операнды и отводить для них целое слово слишком расточительно. При w = 0 (операнд-байт) значение s не играет роли. При w = 1 (операнд-слово): если s=0, то в команде присутствуют все 16 бит DATA, если же s=1, то присутствуют 8 бит (DATA-LO), которые расширяются со знаком до 16-тиразрядного операнда. Благодаря биту s экономится один байт! Это — кодировка с расширением знака (sign-extended encodings).
Упражнение. Выполним в debug ассемблирование и дисассемблирование команд add bx,ff и add bx,ffff. Их коды окажутся следующими:
add bx,ff 81C3FF00
add bx,ffff 83C3FF
Объясните, почему код второй команды оказался короче.
(В ответ. В TD этот эффект можно получить только вводя mov bx,–1)
Казалось бы, мы полностью разобрались с командой ADD. Но есть ещё один её вариант! При выполнении команды сложения приемником, как правило, является аккумулятор (AX или AL). Для прибавления к аккумулятору введена специальная кодировка (укороченный формат ADD):
0 |
0 |
0 |
0 |
0 |
1 |
0 |
w |
|
DATA-LO |
|
DATA-HI |
|
|
|
|
|
|
|
|
|
|
|
присутствует, если w=1 |
Подведем итоги. Создатели микропроцессора 8086 приложили максимум усилий для компактного кодирования команд: для часто используемых вариантов команд имеются сокращенные форматы. Длина команды может составлять от одного до шести байт.
Полученные сведения могут показаться излишними, но теперь вы должны четко понимать, например, почему нельзя использовать адресацию [CX]. Потому что не хватило номеров для методов адресации. Стал ясным запрет на использование в команде двух операндов из памяти.
Еще одно упражнение, которое поможет понять нехитрые программистские трюки для сокращения длины кода программы.
Упражнение. 1) При обработке массива слов для перехода к следующему слову нужно увеличивать на два содержимое индексного регистра. Что короче: две команды inc si или одна команда add si,2 ?