Ассемблер 8051. Инструкция mov A, @A+PC

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Аватара пользователя
Shuspano
Грызет канифоль
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

Ассемблер 8051. Инструкция mov A, @A+PC

Сообщение Shuspano »

Не работает как предполагается. Никогда ей особо не интересовался и не пользовался (типа, зачем она нужна), думал что это просто аналог mov A, @A+DPTR, но с укороченной, 8-битной адресацией. Но щас вот решил попробовать, и получилась ерунда. Написал программку чтоб проверить:

Код: Выделить всё

	org	0
data0	equ	0x20
lenght	equ	strend-string

main:	mov	R0, #data0
		mov	R1, #string
		mov	R7, #lenght
loop:  clr	A
		mov	A, R1
		movc	A, @A+PC
      mov	@R0, A
		inc	R0
		inc	R1
		djnz	R7, loop
		sjmp	$

string:	db	'Hello World'
strend:
		end
Программа копирует строку из памяти программ, и помещает в оперативную память. Но, при прошагивании в отладчике, инструкция берет только два последних символа в строке. Понятно, что неправильное смещение, понятно что с момента когда я положил адрес строки в регистр и до этой инструкции, программный счетчик успел насчитать. Но зачем тогда эта инструкция, если она всегда неправильно работает?
Я нашел два плохих решения - посмотреть в листинге что там натранслировалось, и откорректировать часть адреса которая в A, второе - заставить ассемблер считать "коэффициент коррекции": Добавлена метка после MOVC, а в регистр R1 кладется результат выражения, составленного из меток. Так заработало.

Код: Выделить всё

	org	0
data0	equ	0x20
lenght	equ	strend-string

main:	mov	R0, #data0
		mov	R1, #string-movc_a-main
		mov	R7, #lenght
loop:	clr	A
		mov	A, R1
		movc	A, @A+PC
movc_a:	mov	@R0, A
		inc	R0
		inc	R1
		djnz	R7, loop
		sjmp	$

string:	db	'Hello World'
strend:
		end
Мне кажется ненормальным городить такой огород. Может, я чего-то не понял, и есть более очевидный способ. Или нет?
Реклама
Аватара пользователя
Ser60
Друг Кота
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Re: Ассемблер 8051. Инструкция mov A, @A+PC

Сообщение Ser60 »

зачем тогда эта инструкция, если она всегда неправильно работает?
Инструкция работает всегда правильно, просто для Вашей цели первый вариант кода был неправильный. Но Вы уже сами нашли выход N2, который мне совсем не кажется огородом. См. здесь пример использования этой инструкции для организации lookup-table.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15575
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер 8051. Инструкция mov A, @A+PC

Сообщение BOB51 »

MOVC a,@a+PC штука довольно редкоиспользуемая.
Собственно предназначена для разных перекодировок по содержимому аккумулятора.
Однако имеет хитрости применения, связанные с содержимым А и РС на момент исполнения...
Ибо за самой командой обычно следует или RET или SJMP rel (ajmp addr, ljmp addr)- иначе слопаем изменение содержимого аккумулятора и покатимся далее по счетчику адресов.
А при А=0 начало таблицы есть адрес следующего байта за MOVC a,@a+PC...
Т.е.
один из вариантов применения:

Код: Выделить всё

..........
inc a ; соответствующая длине команды после movc a,@a+pc корректировка содержимого А
movc a,@a+pc
point_zero: ret ; sjmp rel, ajmp addr, ljmp addr 
                      ; это точка продолжения исполнения программы в любом случае и 
                      ; точка размещения возвращаемых в аккумулятор данных при А=0
                      ; без внесения предварительного  дополнительного поправочного коэффициента
table:
................
Обычно оформляется или в виде подпрограммы acell prog --- ret или завершается командой перехода при соответствующей предварительной коррекции содержимого А перед исполнением movc a,@a+pc (когда применяем sjmp rel, ajmp addr, ljmp addr)
8)

Чуть не забыл самую вкусняшку:

Код: Выделить всё

.........
inc a ;
movc a,@a+pc
point_zero: JMP @A+DPTR ;
table:
................
:wink:
Ответить

Вернуться в «Разные вопросы по МК»