Mov в ассемблере: Инструкция MOV

Инструкция MOV


Английский за 3 месяца

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

Пожалуй, инструкция MOV в ассемблере самая простая. Синтаксис этой команды такой:

MOV ПРИЁМНИК, ИСТОЧНИК

С помощью этой команды можно переместить значение из ИСТОЧНИКА в ПРИЁМНИК.

То есть по сути команда MOV копирует содержимое ИСТОЧНИКА и помещает это содержимое в ПРИЁМНИК.

Никакие флаги при этом НЕ изменяются.

При использовании этой команды следует учитывать, что имеются некоторые ограничения. А именно, инструкция MOV не может:

  • Записывать данные в регистры CS и IP.
  • Копировать данные из одного сегментного регистра в другой сегментный регистр (сначала нужно скопировать данные в регистр общего назначения).
  • Копировать непосредственное значение в сегментный регистр (сначала нужно скопировать данные в регистр общего назначения).

ИСТОЧНИКОМ может быть один из следующих:

  • Область памяти (MEM)
  • Регистр общего назначения (REG)
  • Непосредственное значение (например, число) (IMM)
  • Сегментный регистр (SREG)

ПРИЁМНИКОМ может быть один из следующих:

  • Область памяти (MEM)
  • Регистр общего назначения (REG)
  • Сегментный регистр (SREG)

С учётом ограничений, которые были описаны выше, комбинации ПРИЁМНИК-ИСТОЧНИК могут быть следующими:


REG,  MEM
SREG, MEM
MEM,  REG
REG,  REG
SREG, REG
MEM,  IMM
REG,  IMM
MEM,  SREG
REG,  SREG

Пример использования инструкции MOV:


MOV AX, 0B800h    ; установить AX = B800h (память VGA). 
MOV DS, AX        ; копировать значение из AX в DS.
MOV CL, 'A'       ; CL = 41h (ASCII-код).
MOV CH, 01001110b ; CH = атрибуты цвета (желтый текст на красном фоне).
MOV BX, 72eh      ; BX = позиция на экране = 2*(x + y*80).
MOV [BX], CX      ; [0B800h:015Eh] = CX.

ПРИМЕЧАНИЕ
Этот пример не будет работать в Windows 2000 и выше, так как эти операционные системы запрещают программам напрямую обращаться к “железу”, а в этом примере мы пытаемся записать данные непосредственно в видеопамять.

Ну и напоследок скажу, почему эта инструкция называется MOV. Это сокращение от английского слова MOVE, которое можно перевести как “переместить, перенести, передвинуть”. И, как теперь вам уже понятно, эта команда соответствует своему названию — она перемещает значение из одного регистра в другой. Хотя с точки зрения русского языка это будет не совсем правильно, потому что перемещения не происходит — значение из ИСТОЧНИКА никуда не исчезает (не перемещается), по сути оно копируется и вставляется в ПРИЁМНИК.


Подписаться на Дзен-канал

Вступить в группу «Основы программирования»

Подписаться на рассылки по программированию


Первые шаги в программирование

Главный вопрос начинающего программиста – с чего начать? Вроде бы есть желание, но иногда «не знаешь, как начать думать, чтобы до такого додуматься». У человека, который никогда не имел дело с информационными технологиями, даже простые вопросы могут вызвать большие трудности и отнять много времени на решение. Подробнее…


mov Программирование на Ассемблере без знаний Ассемблера, habr / Хабр

Самый короткий мультфильм про программирование.

Пролог

Решил поделиться своими мыслями и кратким двухдневным опытом написания

(собирания по частям) программы на Ассемблере без чтения учебников, больших статей и в целом без опыта программирования на этом языке. На одном из форумов я набрёл на задачу вывода десятичного числа в консоль. Если на языке C или PHP эта операция совершенно элементарна, то на Ассемблере всё не так просто, как может показаться на первый взгляд. Для решения задачи я выбрал nasm (правда, выбора и не было), немножко поигравшись предварительно с вставками nasm (синтаксис AT&T) в код C (ссылка на форум с моими опытами в конце статьи).

Философское отступление
Остановись, дорогой читатель! И прежде чем читать дальше, задай себе вопрос: возможно ли начать ковать без обучения кузнечному делу?!

Я оставлю этот вопрос без ответа. Только скажу, что в нём нет ни капли иронии, издёвки, намёка на назидательность и т.д. Это вопрос без какого-либо дополнительного подтекста.

Поиски
Информации по Ассемблеру в Интернете очень много и заблудиться в разных видах Ассемблера (для различных систем) крайне просто. Я не единственный задавался вопросом в поиске «how to print a number in asm». Ответы на разных диалектах языка относительно легко можно найти на Stack Overflow, однако это совершенно не означает, что будет легко запустить найденный код на своей машине. Велика вероятность того, что что-нибудь не сойдётся. Научиться отличать синтаксис AT&T и intel можно за несколько минут, а вот с узнаванием tasm, fasm, masm, nasm — несколько сложнее. Единственное, что можно предположить и (почти) не прогадать: базовые инструкции во всех Ассемблерах имеют (почти) одинаковые мнемоники.

Ассоциации и первые впечатления

Если хотите, чтобы ваши соседи переехали, убедите себя в том, что играть на скрипке легко…

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

Итак, задача:
Собрать программу, печатающую на стандартный вывод (stdout) число.

Реализация
Принцип (его надо мысленно прокрутить в голове и понять, тогда можно считать, что мы не списываем):

  1. Число делится на 10.

  2. В регистр edx заносится остаток,

    в eax остальная часть.

  3. Остаток в цикле записывается в буфер (stroka), начиная с конца, используется декремент, затем выводится

  4. Дополнительно: при использовании инкремента можно напечатать строку в обратном порядке.

Код nasm (собран на архитектуре 64b, с моими и чужими комментариями)

section .data
 	 stroka db 4;буфер для вывода
section .text
global _start  	;must be declared for using gcc
_start:            ;tell linker entry point
	push rbp       ;Работа со стеком
	mov rbp, rsp
	mov eax, 311  	; 311 - делимое
	mov edi, 3      ; Переменная цикла. 
loop:               ; Начало цикла
      dec edi
					 ; Декремент, чтобы  записать все значения остатка в stroka
    mov ebx, 10      ; Делитель. Запишем  в цикл, чтобы вернуть ему значение на новой итерации. 
                     ; Можно использовать для делителя только часть регистра ebx, а именно bx   
    xor edx, edx     ; Обнулим остаток
    div ebx          ; Делим
    add edx, 30h     ; Добавим в остаток 0, равносильно add edx, '0'
    mov  [stroka + edi], dl ; Пишем в строку остаток в обратном порядке.
    cmp edi,  0       ; Выходим
jne loop              ; Возврат в цикл
                        ; Собрали строку и далее выводим
  	mov ecx, stroka   ; Кладём
    mov     edx, 4      ; Длина выводимой строки  4 (видимо, в байтах)
    mov     ebx, 1      ; file descriptor (stdout)
    mov     eax, 4      ; system call number (sys_write)
    int     0x80         ; call kernel
    mov     eax, 1      ;system call number (sys_exit)
    int     0x80        ;call kernel

Команда для сборки, линковки и выполнения

nasm -f elf64 print_num. asm -o print_num.o; ld -o print_num print_num.o; ./print_num

  • *** Для остатка можно использовать только часть регистра edx, а именно dx. Это же верно и для делителя — можно использовать bx, так как число 10 умещается в 2 байта (16 бит).

  • *** Для счётчика цикла, наверное, лучше использовать регистр ecx (как более канонический вариант), а остановку цикла осуществлять, когда в ax будет 0.

Оставлю для таких же как я дополнительную задачку и подсказку.

Задача: изменить программу так, чтобы число печаталось наоборот.

Подсказка

Hidden text

Менять нужно mov edi, 3; dec edi; cmp edi, 0

Дополнительно: как сделать из нашего «hello world» что-нибудь полезное?

Если немножко почитать про стек, а также регистры rsp, rbp и поиграть со смещением, то можно быстро переделать программу в генератор псевдослучайных чисел:

	mov rbp, rsp
	mov eax, [rbp +17]  	; Забираем из стека по адресу 17 значение
	add eax, [rbp +18]  	; И ещё сместимся на 1 (видимо,1 байт) и добавим в eax

Далее самописный псевдогенератор

section . data
 	 stroka db 4 ;буфер для вывод
section .text
global _start  	 ;must be declared for using gcc
_start:            ;tell linker entry point
	push rbp       ;Работа со стеком
	mov rbp, rsp
	mov eax, [rbp +17]  	; Забираем из стека по адресу 17 значение
	add eax, [rbp +18]  	; И ещё сместимся 1 одно значение, добавим в eax
	mov edi, 3         ; Переменная цикла.
loop:                  ; Начало цикла
      dec edi
					 ;Декремент, чтобы  записать все значения остатка в stroka
    mov ebx, 10      ; Делитель. Запишем  в цикл, чтобы вернуть ему значение на новой итерации
    xor edx, edx     ; Обнулим остаток
    div ebx          ; Делим
    add edx, 30h     ; Добавим в остаток 0, равносильно add edx, '0'
    mov  [stroka + edi], dl ; Пишем в строку остаток в обратном порядке.
    cmp edi,  0          ; Выходим
jne loop               	 ; Возврат в цикл
                         ; Собрали строку и далее выводим
  	mov ecx, stroka     ; Кладём
    mov     edx, 4      ; Длина выводимой строки  4 (видимо, в байтах)
    mov     ebx, 1      ; file descriptor (stdout)
    mov     eax, 4      ; system call number (sys_write)
    int     0x80        ; call kernel
    mov     eax, 1      ;system call number (sys_exit)
    int     0x80        ;call kernel

Источники:

1) https://acm. mipt.ru/twiki/bin/view/Asm/PrintIntFunction

2) http://av-assembler.ru/asm/afd/asm-cpu-registers.htm

3) https://wasm.in/

4) https://codetown.ru/assembler/delenie-umnozhenie/ (про умножение, деление и регистры)

Темы с моими опытами:

https://wasm.in/threads/vyvod-desjatichnogo-chisla.34675/

https://wasm.in/threads/assmembler-vstavkami.34672/

Интересное

Бонус: ссылка на интересный репозитарий, в нём ОС с линковщиком (из трёх файлов: загрзчик, линковщик, ядро,):
https://github.com/cirosantilli/x86-bare-metal-examples/blob/master/c_hello_world/run

Update:

Добавлю решённый мной пример поиска и замены значения в массиве (для таких же как я, на примере можно понять ветвления прогрммы (пропуски, переходы)): https://gitflic.ru/project/dcc0/mix-c-89-php/blob?file=search_and_change_in_array.asm

Данной заметкой цикл статей для хабра завершаю.

Всем спасибо. C наступающим 2023 годом!

Новогодняя микросистема для запуска в qemu:

https://gitflic. ru/project/dcc0/mix-c-89-php/blob?file=cat_on_boot.asm

https://www.youtube.com/watch?v=YGRambq6kXs

Сборка

— Как я могу использовать MOV в ассемблере?

спросил

Изменено 1 год, 4 месяца назад

Просмотрено 1к раз

Я кодирую ASM и совершенно не понимаю правил mov , поэтому

 mov rax, 100 ; это означает, что число 100 находится в rax?
    мов ракс, а ; это означает, что значение a находится в rax? или это направление памяти?
    мов ракс, [а] ; это означает значение a? или что?
    мов [а], ракс ; направление мемори при смене на rax?
    мов ракс, rbx ; rbx теперь rax?
 

Извините, если мой вопрос глупый, но я действительно запутался… спасибо

  • сборка
  • x86
  • x86-64
  • mov

2

Поскольку у нас есть mov rax, 100 как действительный, мы знаем, что это синтаксис Intel. Продолжая и предполагая, что a является меткой, а не макросом или equ, в результате получается константа:

 mov rax, 100 ; Всегда означает поставить константу 100 в rax
мов ракс, а ; Либо означает поместить адрес a в rax,
             ; или поставить в rax смотря какой ассемблер.
             ; Для nasm это всегда адрес a.
мов ракс, [а] ; Всегда означает 8-байтовое значение, хранящееся в
             ; для смещений более 2 ГБ целевой регистр должен быть al, ax, eax или rax
мов [а], ракс ; Поместите значение rax в значение, хранящееся в
мов ракс, rbx ; Поместите значение rbx в rax (без доступа к памяти)
mov rax, [rbx] ; Поместите значение, сохраненное там, где rbx указывает на rax
 

Я добавил последний для полноты картины. Не занимайтесь математикой в ​​[] операциях здесь.

Однако вы редко хотите загружать абсолютные адреса; вы обычно хотите rip-relative, вы обычно должны написать следующее (синтаксис NASM):

 lea rax, [rel a] ; поместить адрес a в rax
mov rax, [отн.  a] ; поместить значение в a в rax
 

11

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя адрес электронной почты и пароль

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Программирование на языке ассемблера

 

В линия сборки
Операторы ассемблера распознаются компилятором.
Единственным исключением является SWAP, потому что это допустимый оператор BASIC.
Вы должны предварить этот оператор ASM знаком !, чтобы компилятор знал что вы имеете в виду оператор ASM SWAP.

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

Пример:
Мов a, #10 ‘хорошо
Mov acc, #10 ‘тоже ок но генерирует еще 1 байт
Setb acc.0 ‘ok
Setb a.0 ‘NOT OK

Вы также можете включить ассемблерный файл с оператором $INCLUDE FILE.ASM .

Ассемблер основан на стандартной мнемонике Intel.
Для описания мнемоники используются следующие коды:


Р-н рабочего регистра R0-R7
Прямые 128 внутренних ячеек ОЗУ, любой порт ввода-вывода, регистр управления или состояния.
Например: P1, P3, АКК
@Ri косвенное внутреннее расположение ОЗУ, адресованное регистром R0 или R1
#data 8-битная константа, включенная в инструкцию
#data16 16-битная константа, включенная в инструкцию
Бит 128 программные флаги, любой вывод ввода-вывода, бит управления или состояния
Например: ACC. 0, P1.0, P1.1

Логический манипулирование переменными:

CLR C прозрачная переноска флаг
Прямой бит очистки CLR
SETB C установить флаг переноса
Бит SETB установлен прямой бит
Флаг переноса дополнения CPL C
Прямой бит дополнения CPL
ANL C, бит И прямой бит для переноса флага
ORL C,bit ИЛИ прямой бит для переноса флага
MOV C,bit Переместить прямой бит для флага переноса

Программа и управление машиной:

LCALL addr16 длинный вызов подпрограммы
Возврат RET из подпрограммы
Возврат RETI из прерывания
LJMP addr16 прыжок в длину
Короткий переход SJMP rel (относительный адрес)
Непрямой переход JMP @A+DPTR относительно DPTR
JZ rel скачок, если accu равен нулю
JNZ rel скачок, если accu не равен нулю
Переход JC rel, если установлен флаг переноса
Переход JNC rel, если флаг переноса не установлен
JB bit,rel переходит, если установлен прямой бит
JNB bit,rel переходит, если прямой бит не установлен
Бит JBC, переход rel, если установлен прямой бит, и сброс бита
CJNE A,direct,rel сравнить прямое с A и перейти не равным
CJNE A,#data,rel comp. я мед. на A и перейти, если не равно
CJNE Rn,#data,rel comp. я мед. к рег. & перейти, если не равно
CJNE @Ri,#data,rel comp. я мед. к инд. & перейти, если не равно
DJNZ Rn,rel регистр уменьшения и переход, если не ноль
DJNZ прямое,относительное уменьшение прямое и переход, если не ноль
NOP Нет операции

Арифметика операции :

ADD A,Rn добавить регистр накопить
ADD A, прямое добавление байта регистра в аккумулятор
ADD A, @Ri добавить непрямую оперативную память в аккумулятор
ADD A,#data добавить немедленные данные в аккумулятор
ADDC A,Rn добавить регистр для переноса
ADDC A, прямое добавление прямого байта в аккумулятор с флагом переноса
ADDC A,@Ri добавить непрямую ОЗУ для накопления с флагом переноса
ADDC A,#data добавить немедленные данные для накопления с флагом переноса
SUBB A,Rn вычесть регистр из A с помощью заимствования
SUBB A, прямое вычитание прямого байта из A с заимствованием
SUBB A, @Ri вычесть непрямую оперативную память из A с помощью заимствования
SUBB A,#data вычесть немедленные данные из A с помощью заимствования
INC Аккумулятор приращений
Регистр приращения INC Rn
INC прямое приращение прямого байта
INC@Ri увеличивает непрямое ОЗУ
Декрементный аккумулятор DEC A
DEC Rn регистр декремента
DEC прямой декремент прямого байта
DEC@Ri косвенное уменьшение ОЗУ
INC DPTR приращение указателя данных
MUL AB умножить A и B
DIV AB разделить A на B
DA Аккумулятор десятичной корректировки

Логический операции :

АНЛ А,Рн И регистр для накопления
ANL A,прямой И прямой байт для аккумулятора
ANL A,@Ri И непрямая оперативная память для накопления
ANL A,#data И немедленные данные для накопления
ANL direct,A AND accu to direct byte
ANL direct,#data И немедленные данные для прямого байта
ORL A,Rn ИЛИ зарегистрироваться в аккум
ORL A,прямой ИЛИ прямой байт для накопления
ORL A,@Ri ИЛИ непрямое ОЗУ для аккумулятора
ORL A,#data ИЛИ немедленные данные для накопления
Прямой ORL,Аккумулятор ORL для прямого байта
ORL direct,#data ORL немедленные данные для прямого байта
XRL A,Rn исключительный регистр ИЛИ для накопления
XRL A, прямой исключающий ИЛИ прямой байт для накопления
XRL A, @Ri эксклюзивная ИЛИ непрямая RAM для накопления
XRL A,#данные эксклюзивные ИЛИ немедленные данные для накопления
XRL direct, Эксклюзивное ИЛИ накапливается в прямом байте
Прямой XRL, #данные эксклюзивные ИЛИ немедленные данные для прямого байта
CLR A четкий аккумулятор
Аккумулятор CPL A
RL A повернуть аккумулятор влево
RLC A повернуть A влево через флаг переноса
RR A повернуть аккумулятор вправо
RRC A повернуть аккумулятор вправо через флаг переноса
SWAP Замена битов в аккумуляторе

Данные перевод :

MOV A,Rn регистр перемещения для накопления
MOV A, прямое перемещение прямого байта в аккумулятор
MOV A,@Ri переместите непрямую оперативную память в аккумулятор
MOV A,#data перемещает немедленные данные в аккумулятор
MOV Rn,A ход аккум на регистр
MOV Rn, прямое перемещение прямого байта в регистр
MOV Rn,#data перемещает немедленные данные в регистр
MOV direct, A перенос в прямой байт
MOV direct,Rn переместить регистр в прямой байт
MOV прямое, прямое перемещение прямого байта в прямое
MOV direct, @Ri перемещает непрямую RAM в прямой байт
MOV direct,#data перемещает немедленные данные в прямой байт
MOV@Ri, перемещение в стороннюю ОЗУ
MOV@Ri, прямое перемещение прямого байта в непрямое ОЗУ
MOV@Ri,#данные перемещаются немедленно в непрямую ОЗУ
MOV DPTR,#data16 загружает указатель данных с 16-битной константой
. MOVC A,@A+DPTR переместить байт кода относительно DPTR в A
MOVC A,@A+PC переместить байт кода относительно ПК в A
MOVX A,@Ri перемещает внешнюю RAM (8-битную) в A
MOVX A,@DPTR переместить наружу; ОЗУ (16 бит) до А
MOVX@Ri,A переместить A во внешнюю RAM (8-битную)
MOVX@DPTR,A переместить A во внешнюю RAM (16-разрядную)
PUSH прямой ввод прямого байта в стек
POP прямое извлечение прямого байта из стека
Регистр обмена XCH A,Rn с аккумулятором
XCH A, прямой обмен прямым байтом с аккумулятором
XCH A,@Ri обмениваются косвенной оперативной памятью с A
XCHD A,@Ri обмен младшим разрядом инд. ОЗУ ж. А

Как для доступа к меткам из ASM.
Каждая метка в BASCOM заменяется точкой, за которой следует имя метки.

Пример:
ПЕРЕЙТИ Тест
Тест:

сгенерированный код ASM:
LJMP. Тест
.Тест:

Когда вы используете Перед ASM-метками вы также можете поставить перед ними знак !, чтобы метка не быть преобразованы.
Jb P1.0, тест; без периода
!test : ;указать метку ASM

Или вы можете включить точка в имени метки.
Другой хорошей альтернативой является использование директив $ASM $END ASM.

Пример:
$Asm
мов а,#1
тест:
тест sjmp
$End Asm

Как переменные сохраняются.
Переменные BIT хранятся в байтах.
Эти байты хранятся от 20hex до 2Fhex, что позволяет получить 16 * 8 = 128 бит. переменные.
Вы можете получить доступ к битовой переменной следующим образом:

Тусклый var As Bit ‘dim переменная
SETB {var} ; установить бит
CLR {var} ; очистить бит
Print var ; распечатать значение
Конец

Или вы можете использовать БАЗОВЫЕ операторы SET и RESET, которые делают то же самое.


Переменные BYTE хранятся после переменных BIT.

Начиная с адреса 20 hex + (используемые байты для битовых переменных).

INTEGER/WORD переменные хранятся с младшим битом в самой нижней позиции памяти.
Переменные LONG также хранятся с младшим битом в самой нижней позиции памяти.

Вы можете получить доступ к переменным окружив переменную символом {.
Чтобы обратиться к MSB целого числа/слова, используйте var+1.
Чтобы обратиться к старшему биту Long, используйте var+3.

Следующий пример показывает, как получить доступ к переменным из ASM

Тусклый t как байт, c как целое число
CLR a ; очистить регистр
МОВ {т}, а ; очистить переменную t
INC {t} ; t=t + 1
MOV {c}, {t}; с = t
MOV {c+0}, {t} ; младший бит из C = t (вам не нужно вводить +0)
MOV {lain+1}, {t} ; старший бит C = t
MOV {c},#10 ; назначать значение

Вы также может изменять SFR из BASIC.
P1 = 12 ‘это очевидно
ACC = 5 ‘это нормально тоже
f0 B = 3 ‘B тоже SFR
MUL AB ‘акк = акк * б

Printcf0 согл.

ВНЕШНИЕ переменные хранятся аналогично.
Строки сохраняются с завершающим нулем.

Пример:

$RAMSTART = 0
Dim s As String * 10 ‘зарезервировать 10 байт + 1 для ограничителя строки
s = «abcde» ‘присвоить строковую константу строке

расположение оперативной памяти 0 = a ‘первое место в памяти
расположение плунжера 1 = b
местоположение барана 2 = c
положение поршня 3 = d
расположение поршня 4 = e
расположение плунжера 5 = #0


Доступ к внешним переменным должен осуществляться несколько иначе.

Тусклый T как байт XRAM

движения дптр,#{T} ; адрес T к указателю данных
mov a,#65 ; место А в соотв.
movx @dptr,a ; переместить во внешнюю память
Print T ; распечатать это от базового

Тусклый T1 как целое число XRAM
mov dptr,#{T1} ; набор указатель данных
mov a,#65 ; место А в соотв. (LSB)
movx @dptr,a ; переместить на внешнюю память
вкл дптр ; переместить указатель данных
mov a,#1 ; от 1 до MSB
movx @dptr,a ; перенести на внешнюю память

Распечатать Т1 ; распечатать из базового


Вспомогательные процедуры
Есть две новые вспомогательные процедуры ASM, которые могут немного упростить задачу:

.

МЕСТОЗНАЧЕНИЕ var , SFR
PLACEADRES var, SFR

PLACEVALUE присваивает переменная var в указанный регистр SFR.
Placevalue 1, A сгенерирует:
Mov a,#1

Dim x как байт
Placevalue x ,R0 будет генерировать:
Мов а, h’3A ; в этом примере конечно только

Где это становится удобно с массивами:
Placevalue a(x), RO сгенерирует:

мов r0,#h’3A
Мов а,@r0
Rl a
Добавить a,#h’1F
Mov R0,a
Мов а,@r0

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

Вы можете назначить только 1 SFR с оператором PLACEVALUE.
Именно здесь за углом появляется PLACEADRES.
Placeadres помещает адрес переменной в регистр.

Адрес ar(x),A
Placeadres z , R0

Когда внешние переменные используются, вам не нужно указывать регистр, потому что DPTR всегда назначенный.

Тусклый X as xram Integer
PLACEADRES x , dptr или PLACEADRES х
Будет сгенерировано:
Mov dptr,#2

Или с массивами :
МЕСТААДРЕСА ар(х)

мов dptr,#2
Mov r0,#h’37

мов a,@r0
Mov r2,a
Inc r0
Mov a,@r0
Mov r3,a
Mov r1,#1
Acall _AddIndex

Конечно, это также примеры, сгенерированный код зависит от типов и если они внутренние или внешние переменные.

Шестнадцатеричный обозначение
Вы также можете использовать шестнадцатеричное представление.
Пример: Мов а,#ч’АА
Или используйте ОСНОВНУЮ нотацию:
Mov a,#&HAA

Двоичный обозначение
Вы также можете использовать двоичную запись.
Пример: Мов а,#&B10001000


Прыжки со смещением

Вы можете указать смещение вместо имени метки при прыжке.
Джб P1.0 , *+12 ;переход вперед
Jb P1.0 , *-12 ;переход назад
Jnb P1.0 , *+0 ;петля пока P1.0 не станет высоким

Это также относится к другим инструкциям, где можно перейти к метке, такой как SJMP, LJMP DJNZ и др.

Внутренний буфер для преобразования строк
Процедуры преобразования строк, используемые для PRINT num, STR() и VAL(), используют внутренний буфер 16 байт. Это имеет то преимущество, что нет обработки стека необходим, но недостатком является то, что используется фиксированное пространство.

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *