MSP430 - учебный курс. Часть 3 - ядро, память и режимы адресации.

План на сегодня таков:
1. Ядро — краткий обзор.
2. Словный и байтный формат команд.
3. Структура памяти.
4. Режимы адресации.
Начнем, пожалуй.
Кстати, пришел заказанный MSP430F247 — ура! Ну а пока я к нему привыкаю, рассмотрим мой любимый MSP430F149.
Это старшая модель в семействе MSP430x1xx — лапы и периферия по максимуму.
Кратенько характеристики:
— Тактовая частота — до 8 МГц.
— Три источника тактирования — один внутренний и два внешних.
— 64 ноги (в корпусе QFP c шагом 0.5 мм).
— ОЗУ — 2Кб.
— ПЗУ (типа FLASH) — 60 Кб.
— ЭСППЗУ (EEPROM) — 256 б.
— 6 групп портов ввода/вывода (43 порта) — пять по 8 и один 3 линии.
— 16-ти битные таймеры (2 штуки, но очень хитрые).
— 12 бит АЦП, компаратор.
— SPI, USART.
— JTAG.
— Аппаратный умножитель (нет специальной команды умножения).
Вот внутренняя структура семейства:

Внутренний источник тактирования DCO (Digital Controlled Oscillator) построен на RC-цепочке и имеет частоту около 750 кГц (сильно зависит от температуры).
Внешние источники:
LFXT1 — работает в двух режимах: высокочастотном (450 кГц… 8 МГц) и низкочастотном (оптимизирован под часовой кварц 32768 Гц).
XT2 — высокочастотный — 450 кГц… 8 МГц.
Выбор источника тактирования осуществляется программно. При этом, по умолчанию запускается на встроенном. Если мы пытаемся подключить внешний источник и нам это не удалось, контроллер вернётся к работе на встроенный и не зависнет.
1. Ядро
Основное о ядре:
— 16-ти битная шина адреса (адресует до 64 Кб памяти).
— 16-ти битная шина данных.
— Ортогональная архитектура (любой режим адресации пригоден для команды, правда есть заморочки для второго операнда).
— 16 регистров (4 РСН и 12 РОН) — все могут быть указателями.
— Прямой обмен «память -> память».
— 51 команда: 27 команд ядра (аппаратных) и 24 эмулированных (псевдонимы).
— Байтный и словный формат команд.
— Генератор констант, сокращающий код в определённых случаях.
Регистры кратко.
R0 — PC (program counter) — счётчик команд.
R1 — SP (stack pointer) — указатель стека. Не забудьте инициализировать!
R2 — SR (status register) — регистр состояния и управления. Содержит основные флаги состояния, а также флаги управления режимами работы.
R3 — CG (constant generator) — генератор констант.
R4..R15 — просто регистры общего назначения.
Эмулированные команды — это фикция компилятора. В конечном итоге они будут заменены на какую-либо команду с определённой комбинацией операндов. К примеру «NOP» заменяется на «MOV #0, R3».
О генераторе констант поговорим подробнее позже.
2. Словный и байтный формат команд.
Все команды, кроме переходов, поддерживают как побайтное обращение к операндам, так и пословное (2 байта).
При написании команды ставится признак типа обращения.
Например:
mov R4, R5 ; пословная форма, по умолчанию
mov.w R4, R5 ; пословная форма, с явным указанием
mov.b R4, R5 ; побайтная форма, только с явным указанием
Здесь мы копируем содержимое регистра R4 в R5.
В последнем случае, в младший байт R5 будет помещен младший байт R4, а в старший байт R5 будет помещен 0.
Обращение к байтам — как по чётным, так и по нечётным адресам. К словам — только по чётным.
3. Структура памяти.
Распределение памяти в контроллере интересное. Т.к. Архитектура Фон-Неймана, то всё находиться в едином адресном пространстве памяти (если кто знаком с x86, тот знает, что там есть ещё одна адресная ось — регистры ввода/вывода, в MSP430 этого нет). Полюбуйтесь:

Внимание! На картинке показано не всё (без BSL и ЭСППЗУ), см. описание ниже.
Диапазон адресов — 0000h..000Fh.
В самом низу — регистры специального назначения (не путать с регистрами в ядре!). Их состав зависит от конкретной модели микроконтроллера и предназначены они для работы с некоторыми функциями периферии. Обращение — побайтное.
Диапазон адресов — 0010h..00FFh.
Здесь находятся восьмиразрядные регистры модулей периферии. Обращение — побайтное.
Диапазон адресов — 0100h..01FFh.
Здесь находятся шестнадцатиразрядные регистры модулей периферии. Обращение — побайтное и пословное.
Первые три области памяти в IAR отображаются как тип SFR вместе — будьте внимательны.
Диапазон адресов — 0200h..09FFh.
ОЗУ. Начальный адрес фиксирован (0200h). Конечный адрес зависит от объёма памяти в микроконтроллере. Я указал для 2Кб. Обращение — побайтное и пословное.
Диапазон адресов — 0C00h..0FFFh.
Область BSL (Bootstrap Loader). Предустановленный загрузчик, работает через USART. Пока трогать не будем.
Диапазон адресов — 1000h..10FFh.
ЭСППЗУ (EEPROM). Тут всё понятно.
Диапазон адресов — 1100h..FFFFh.
ПЗУ. Конечный адрес фиксирован (FFFFh), начальный зависит от модели микроконтроллера (по объёму ПЗУ). Я привёл для 60 Кб.
Старшие 16 слов ПЗУ отведены под вектора прерывания. Самый последний всегда RESET, остальное зависит от модели.
Обращение — побайтное и пословное.
Размещение слова в памяти — младшая часть по меньшему адресу, старшая часть по большему адресу (little-endian, совпадает с принятым в архитектуре x86).
4. Режимы адресации.
Вот тут самое интересное место.
У MSP430 семь режимов адресации (в реальности меньше, некоторые являются модификациями).
1. Регистровый.
Пересылка из/в регистр. Например:
mov R4, R5 ; поместить содержимое R4 в R5
Применим к источнику и приёмнику.
2. Индексный.
Пересылка с применением регистра в качестве указателя и смещением.
mov R4, 2(R5) ; поместить содержимое R4 в ячейку памяти с адресом [2+R5]
или
mov 0(R4), 4(R5) ; поместить содержимое ячейки памяти с адресом [0+R4] в ячейку памяти с адресом [4+R5]
Смещение(я) идет после кода команды, посему может быть 0..65535.
Применим к источнику и приёмнику.
3. Символьный режим.
Пересылка с исчислением смещения от PC.
mov R4, Dest ; поместить содержимое R4 в ячейку памяти с адресом Dest
или
mov Src, R4 ; поместить содержимое ячейки памяти с адресом Src в R4
Зверюка похитрее, но на самом деле оказывается модификацией индексного режима. Т.е. данная команда эквивалентна
mov R4, X(PC)
или
mov Y(PC), R4
Где Х = Dest-PC, т.е. разнице содержимого программного счетчика и адреса Dest. Аналогично, для второй Y = Src — PC.
Но! Тут кроется большущий подводный камень. Нельзя указывать в операнде значение адреса цифрами, только символьное имя метки. Вернее не совсем нельзя, просто иначе компилятор творит чудеса и вы не получите ожидаемый результат.
mov Val1, R7 ; можно
mov 0x200, R7 ; нельзя!
mov R6, Val1 ; можно
mov R6, 0x200 ; нельзя!
Val1 у меня расположен по адресу 200h.
Данный режим, чаще всего, используется для создания перемещаемого кода, исполняемого в ОЗУ.
Применим к источнику и приёмнику.
4. Абсолютный режим.
Пересылка по адресу, указываемому в коде команды. Адрес должен быть известен на момент компиляции.
mov R4, &Dest ; поместить содержимое R4 в ячейку памяти с адресом Dest
или
mov &Src, R4 ; поместить содержимое ячейки памяти с адресом Src в R4
Вроде бы операции такие же, как и в примере к предыдущему режиму, но адрес не вычисляется, а берется непосредственный.
Поэтому здесь можно указывать адрес цифрами.
mov R4, &0x200 ; поместить содержимое R4 в ячейку памяти с адресом 200h
или
mov &0x200, R4 ; поместить содержимое ячейки памяти с адресом 200h в R4
Применим к источнику и приёмнику.
5. Косвенный регистровый режим.
Пересылка по адресу, указанному в регистре (здесь без смещения).
mov @R4, R5 ; поместить содержимое ячейки с адресом [R4] в R5
Применим только к источнику.
6. Косвенный регистровый режим с автоинкрементом.
Пересылка по адресу, указанному в регистре (здесь без смещения).
mov @R4+, R5 ; поместить содержимое ячейки с адресом [R4] в R5, после чего увеличить R4 на 2
Применим только к источнику.
7. Непосредственный режим.
Пересылка значения.
mov #0x200, R5 ; поместить число 200h в R5
или
mov #Val1, R5 ; поместить значение адреса Val1 в R5
или
call #Sub1 ; вызвать подпрограмму по адресу [Sub1]
Применим только к источнику.
Относительно последней строчки примера — так нужно делать для call, но не для jmp.
Ну всё, я спать, а на следующем уроке рассмотрим генератор констант и систему тактирования.
А для затравки пример по режимам адресации.
#include "msp430.h" ; #define controlled include file
NAME main ; module name
PUBLIC main ; make the main label vissible
; outside this module
ORG 0FFFEh
DC16 init ; set reset vector to 'init' label
RSEG CSTACK ; pre-declaration of segment
RSEG CODE ; place program in 'CODE' segment
init: MOV #SFE(CSTACK), SP ; set up stack
main: NOP ; main program
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; Stop watchdog timer
nop
mov PC, R7
mov #0x200, R4 ; поместить число 200h в R4
; Регистровый
mov R4, R5 ; поместить содержимое R4 в R5
; Индексный
mov R4, 2(R5) ; поместить содержимое R4 в ячейку памяти с адресом [2+R5]
mov 0(R4), 4(R5) ; поместить содержимое ячейки памяти с адресом [0+R4] в ячейку памяти с адресом [4+R5]
; Символьный
mov Val1, R6 ; поместить содержимое ячейки Val1 в R6
mov 0x200, R7 ; а так нельзя !!!
mov Const1, R6 ; поместить содержимое ячейки Const1 в R6
mov Const2, R7 ; поместить содержимое ячейки Const2 в R7
mov R6, Val1 ; поместить содержимое R6 в ячейку Val1
mov R7, 0x200 ; а так нельзя !!!
; Абсолютный
mov &Val1, R7 ; поместить содержимое ячейки Val1 в R7
mov &0x200, R6 ; поместить содержимое ячейки с адресом 200h в R6
mov &Const1, R6 ; поместить содержимое ячейки Const1 в R6
mov &Const2, R7 ; поместить содержимое ячейки Const2 в R7
mov R7, &Val1 ; поместить содержимое R7 в ячейку Val1
mov R6, &0x200 ; поместить содержимое R6 в ячейку с адресом 200h
; Косвенный регистровый
mov @R4, R5 ; поместить содержимое ячейки с адресом [R4] в R5
; Косвенный регистровый с автоинкрементом
mov @R4+, R5 ; поместить содержимое ячейки с адресом [R4] в R5, после чего увеличить R4 на 2
mov @R4+, R5 ; поместить содержимое ячейки с адресом [R4] в R5, после чего увеличить R4 на 2
mov @R4+, R5 ; поместить содержимое ячейки с адресом [R4] в R5, после чего увеличить R4 на 2
; Непосредственный
mov #0x200, R4 ; поместить число 200h в R4
mov #Val1, R5 ; поместить значение адреса Val1 в R5
call #Sub1 ; вызвать подпрограмму по адресу [Sub1]
JMP $ ; jump to current location '$'
; (endless loop)
Sub1:
nop ;
ret ;
; RAM definition
RSEG DATA16_N
Val1:
DS16 1
; ROM definition
RSEG DATA16_C
Const1:
DC16 0x5AA5
Const2:
DC16 0x0FF0
END
P.S.
Некоторые замечания по материалу (так сказать вдогонку).
Замечание 1. По режимам адресации.
Т.к. регистры ядра не имеют физического адреса, выражаемого числом, то к ним неприменимы следующие режимы адресации:
— символьный;
— абсолютный;
— непосредственный.
Замечание2. По байтному и словному доступу.
В словном режиме недопустимо обращение по нечётным адресам памяти!
При обмене «регистр -> память»:
— при словном режиме младшая часть регистра помещается по меньшему (чётному) адресу, старшая по следующему (+1).
— при байтном режиме по адресу обращения помещается младшая часть, старшая игнорируется.
При обмене «память -> регистр»:
— при словном режиме в младшую часть регистра помещается значение из меньшего (чётного) адреса, в старшую из следующего (+1).
— при байтном режиме в младшую часть регистра помещается значение из ячейки по адресу обращения, в старшую заносится 0.
Замечание 3. Регистр PC (aka R0).
Инкремент счетчика команд (только на число, кратное 2!) происходит в момент предшествующий дешифрации команды, после выборки. Это значит, что на момент исполнения команды, счётчик команд указывает на следующую команду. Т.е. код:
mov PC, R4
даст нам в R4 указатель не на эту команду, а на следующую (в данном случае +2).

- 0
- 16 марта 2011, 05:16
- SerjT
Я присоеденяюсь к AKL: желательно начать с более новых value line процессоров — потому что у многих для опытов есть например тот же LaunchPad который стоит копейки (~5$). Исходя из практики — будут чаще использовать именно маленкие процессоры с в маленьком корпусе. Я вот например получиз задание сделать логер с питанием от батарейки 1,5в и так как ПИК я не люблю а АВР немогу заставить уже жрать меньше — купил себе именно LaunchPad и к нему несколько разных процссоров дополнительно. То что асемблер — я думаю нестрашно… Но будет лучше если будет описан способ использования вставок АСМ в С. Потому что из опыта известно что пишется в основном на С и потом оптимализируется вставками :)
Здравствуйте. Приветствую появление материалов по MSP430. Хотелось, что бы в последующем были отражены или акцентированы некоторые моменты
-появление в серии новых подсемейств не заставляет дрожать по поводу снятия с производства старых.
Они по прежнему остаются активными, т.к. это политика TI
-порты ввода-вывода имеют 8-разрядную шину и обращение к ним осуществляется командами MOV.B
-контроллеры не имеют каких бы то ни было битов конфигурации. Все отдано на откуп программисту
-система команд взята в основном от PDP11 и имеет всего 27 базовых команд, включая команды работы в десятичной арифметике. За счет эмуляции ассемблер поддерживает 51 команду
-развитая система режимов пониженного потребления и очень быстрая смена частоты тактирования
-из практики применения. MSP430 весьма живучи.
-хотелось бы увидеть связь с внешней средой. Хоть светиком помыргать. Сначала программно, потом таймером и т.д.
-начальная ориентация на старший камень в подсемействе, боюсь оттолкнет потенциальных юзеров. Здесь и вопросы цены и аппаратной поддержки. Думаю, не каждый рискнет начать с 64-лапой F147(148,149) в QFP или QFN корпусах, а вот F1121 в SOIC более реально.
-очень важный вопрос это программирование
-появление в серии новых подсемейств не заставляет дрожать по поводу снятия с производства старых.
Они по прежнему остаются активными, т.к. это политика TI
-порты ввода-вывода имеют 8-разрядную шину и обращение к ним осуществляется командами MOV.B
-контроллеры не имеют каких бы то ни было битов конфигурации. Все отдано на откуп программисту
-система команд взята в основном от PDP11 и имеет всего 27 базовых команд, включая команды работы в десятичной арифметике. За счет эмуляции ассемблер поддерживает 51 команду
-развитая система режимов пониженного потребления и очень быстрая смена частоты тактирования
-из практики применения. MSP430 весьма живучи.
-хотелось бы увидеть связь с внешней средой. Хоть светиком помыргать. Сначала программно, потом таймером и т.д.
-начальная ориентация на старший камень в подсемействе, боюсь оттолкнет потенциальных юзеров. Здесь и вопросы цены и аппаратной поддержки. Думаю, не каждый рискнет начать с 64-лапой F147(148,149) в QFP или QFN корпусах, а вот F1121 в SOIC более реально.
-очень важный вопрос это программирование
Постепенно всё это будет.
Сначала закончу основное по ядру, потом перейдём к портам, таймерам и прочей периферии.
Просто я даю материал так, чтобы народ мог начать не имея аппаратуры. Изучить команды, можно в программной эмуляции в IAR.
Насчёт новых серий — я специально приобрёл 247-й, чтобы потом перейти к отладке в PROTEUS, т.к. и кристалл достаточно новый, и отличий от соток немного, и в библиотеках PROTEUS он есть.
А насчет маленьких — так там отличия будут в количестве периферии и ног, остальное одинаково. Просто у меня уже есть отладочный комплект с панелькой под 64 ноги, а приобретать что-то новое сложновато. Если у кого-то имеется бесхозная плата под FET140 (LPT-шный) для маленьких кристаллов — сообщите. Рассмотрю возможность приобретения (только я аж в Севастополе).
Программирование тема ещё та. Если есть LPT, то несложно сообразить простой программатор по схеме от TI. Она в свободном доступе, описана в документации на FET. Но для USB — проблема. Если для AVR полно схем и прошивок, то для MSP практически ничего нет.
Так что жду ещё пожеланий. Завтра постараюсь выкатить четвертый урок.
Сначала закончу основное по ядру, потом перейдём к портам, таймерам и прочей периферии.
Просто я даю материал так, чтобы народ мог начать не имея аппаратуры. Изучить команды, можно в программной эмуляции в IAR.
Насчёт новых серий — я специально приобрёл 247-й, чтобы потом перейти к отладке в PROTEUS, т.к. и кристалл достаточно новый, и отличий от соток немного, и в библиотеках PROTEUS он есть.
А насчет маленьких — так там отличия будут в количестве периферии и ног, остальное одинаково. Просто у меня уже есть отладочный комплект с панелькой под 64 ноги, а приобретать что-то новое сложновато. Если у кого-то имеется бесхозная плата под FET140 (LPT-шный) для маленьких кристаллов — сообщите. Рассмотрю возможность приобретения (только я аж в Севастополе).
Программирование тема ещё та. Если есть LPT, то несложно сообразить простой программатор по схеме от TI. Она в свободном доступе, описана в документации на FET. Но для USB — проблема. Если для AVR полно схем и прошивок, то для MSP практически ничего нет.
Так что жду ещё пожеланий. Завтра постараюсь выкатить четвертый урок.
Вы хоть напишите — нормально изложен материал или что-то изменить, рассказать подробнее. А то я без отзывов не могу понять — нужно это или нет.
Пожелания приветствуются: что хотелось бы увидеть поскорее. Я планирую ещё урок по ядру, а потом переходим к портам. Затем таймеры.
Не могу сказать, что я профессионально занимаюсь этим контроллером — только второй семестр веду лабораторные занятия по нему. В инженерной деятельности не применяю, там у меня царство PIC. Поэтому мог что-то упустить. В общем — пишите чаше и я буду в курсе того, что необходимо.
Пожелания приветствуются: что хотелось бы увидеть поскорее. Я планирую ещё урок по ядру, а потом переходим к портам. Затем таймеры.
Не могу сказать, что я профессионально занимаюсь этим контроллером — только второй семестр веду лабораторные занятия по нему. В инженерной деятельности не применяю, там у меня царство PIC. Поэтому мог что-то упустить. В общем — пишите чаше и я буду в курсе того, что необходимо.
Ну например у меня есть вот этот девайс LaunchPad и стоит он и с УСБ отладкой 4,3 долара!!!
Ты эти цены украинским поставщикам покажи…
И ещё найди того, кто их к нам привезёт.
Думаю долларов 15-20 за штуку здесь посчитают оскорблением.
Да и ограничена серия G в возможностях слегонца…
И ещё найди того, кто их к нам привезёт.
Думаю долларов 15-20 за штуку здесь посчитают оскорблением.
Да и ограничена серия G в возможностях слегонца…
То что ограничена — это ясно… Но цена, розмеры чипа и потребление подходя как нельзя лучше! Мне надо думать в фирме не только о том как сделать но и за сколько сделать :) А то что вас там тупо дурят — это ваши проблемы — я заказывал прямо от TI и всё пришло за ту цену как написали. Возможно играет роль и то что я живу в европе :)
Да Вы, батенька, хорошо живёте…
Вы с нашими акулами бизнеса не сталкивались. И это не совсем наши проблемы. И с оплатой «в туда» геморрой.
А по поводу экономической эффективности — все мы об этом думаем. Просто у меня есть в наличии определённый инструментарий и тратить деньги на новый пока мне не выгодно — деньги зарабатываю на другом :-)
По серии G статьи пишет _YS_ и нет смысла его дублировать.
Вы с нашими акулами бизнеса не сталкивались. И это не совсем наши проблемы. И с оплатой «в туда» геморрой.
А по поводу экономической эффективности — все мы об этом думаем. Просто у меня есть в наличии определённый инструментарий и тратить деньги на новый пока мне не выгодно — деньги зарабатываю на другом :-)
По серии G статьи пишет _YS_ и нет смысла его дублировать.
Стиль Мне нравится. Вроде так лаконично, четко и по делу. А вот вопросы будут потом, когда народ ковыряющий сейчас MSP нагуглит эти статьи. Просто процы эти не сильно распространены (в том числе потому что мало инфы толковой и понятной) и количество пользователей сайта кто способен задать вопросы пока мало.
Спасибо за статью, отличное изложение. Несмотря на то, что я уже вроде как освоился с MSP430 по английским мануалам, все равно объяснение на русском, да еще и с комментариями профи, очень помогает проникнуться до конца.
>«Я присоеденяюсь к AKL: желательно начать с более новых value line процессоров — потому что у многих для опытов есть например тот же LaunchPad который стоит копейки (~5$).»
Там все то же самое — то же ядро, та же периферия. Разница только в ее количестве. Это я Вам как лаунчпадовод говорю.
>«Но будет лучше если будет описан способ использования вставок АСМ в С.»
Лично я использую функции, целиком написанные на ассемблере и оформленные в отдельный модуль. Если владеете языком вероятного противника, Вам поможет аппноут от TI на эту тему. Вкратце — первые два параметра передаются в регистрах [R13:]R12 и [R15:]R14 (регистры в квадратных скобках исользуются только если параметр больше 16 бит), остальное — в стеке начиная с последнего параметра. Результат возвращается в [R13:]R12.
Ассемблерный листинг имеет расширение .s43 и следующую структуру:
#include «специфичный_для_МК_заголовочник.h»
NAME имя_модуля
PUBLIC имя_функции1, имя_функции2,…
RSEG CODE
имя_функции1:
[код функции на ассемблере, ровно такой, как описано]
ret
…
END
В С пишем
extern [тип] имя_функции1([параметры]);
Все. Можно использовать. Как видно, никакой особой хитрости (в первом приближении).
>«Я присоеденяюсь к AKL: желательно начать с более новых value line процессоров — потому что у многих для опытов есть например тот же LaunchPad который стоит копейки (~5$).»
Там все то же самое — то же ядро, та же периферия. Разница только в ее количестве. Это я Вам как лаунчпадовод говорю.
>«Но будет лучше если будет описан способ использования вставок АСМ в С.»
Лично я использую функции, целиком написанные на ассемблере и оформленные в отдельный модуль. Если владеете языком вероятного противника, Вам поможет аппноут от TI на эту тему. Вкратце — первые два параметра передаются в регистрах [R13:]R12 и [R15:]R14 (регистры в квадратных скобках исользуются только если параметр больше 16 бит), остальное — в стеке начиная с последнего параметра. Результат возвращается в [R13:]R12.
Ассемблерный листинг имеет расширение .s43 и следующую структуру:
#include «специфичный_для_МК_заголовочник.h»
NAME имя_модуля
PUBLIC имя_функции1, имя_функции2,…
RSEG CODE
имя_функции1:
[код функции на ассемблере, ровно такой, как описано]
ret
…
END
В С пишем
extern [тип] имя_функции1([параметры]);
Все. Можно использовать. Как видно, никакой особой хитрости (в первом приближении).
Перечитал еще раз, много думал.
Все же небольшой вопрос: я правильно понимаю, что режимы 0(reg) и @reg суть одно и то же с той лишь разницей, что первый применим исключительно к источнику и поддерживает автоинкремент?
Т.е.
mov 0(reg1),reg2
равносильно
mov @reg1,reg2
и можно писать
mov reg1,0(reg2)
но нельзя
mov reg1,@reg2
и нельзя
mov 0(reg1)+,reg2?
Все же небольшой вопрос: я правильно понимаю, что режимы 0(reg) и @reg суть одно и то же с той лишь разницей, что первый применим исключительно к источнику и поддерживает автоинкремент?
Т.е.
mov 0(reg1),reg2
равносильно
mov @reg1,reg2
и можно писать
mov reg1,0(reg2)
но нельзя
mov reg1,@reg2
и нельзя
mov 0(reg1)+,reg2?
Истину глаголешь…
По первому примеру — да, фактически действия равносильны, НО…
mov 0(reg1),reg2
порождает лишнее слово в коде (смещение после кода команды) и увеличивает на 1 такт исполнение команды (надо выбрать операнд из памяти). И опять НО! Компилятор не дурак, он просто подменит индексное обращение со смещением 0 на косвенное. Т.е., вместо "mov 0(reg1),reg2" он поставит "mov @reg1,reg2".
Второе
Третье
По первому примеру — да, фактически действия равносильны, НО…
mov 0(reg1),reg2
порождает лишнее слово в коде (смещение после кода команды) и увеличивает на 1 такт исполнение команды (надо выбрать операнд из памяти). И опять НО! Компилятор не дурак, он просто подменит индексное обращение со смещением 0 на косвенное. Т.е., вместо "mov 0(reg1),reg2" он поставит "mov @reg1,reg2".
Второе
и можно писатьименно, т.к. косвенный режим для приёмника не поддерживается (кажется ограничение по длине команды, как и в других процах — просто бит не хватило)
mov reg1,0(reg2)
но нельзя
mov reg1,@reg2
Третье
и нельзятоже нет, т.к. для индексного режима нет автоинкремента.
mov 0(reg1)+,reg2
Комментарии (16)
RSS свернуть / развернуть