Страница 1 из 1

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

Добавлено: Чт авг 20, 2020 00:56:15
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
Мне кажется ненормальным городить такой огород. Может, я чего-то не понял, и есть более очевидный способ. Или нет?

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

Добавлено: Чт авг 20, 2020 01:27:54
Ser60
зачем тогда эта инструкция, если она всегда неправильно работает?
Инструкция работает всегда правильно, просто для Вашей цели первый вариант кода был неправильный. Но Вы уже сами нашли выход N2, который мне совсем не кажется огородом. См. здесь пример использования этой инструкции для организации lookup-table.

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

Добавлено: Чт авг 20, 2020 08:53:57
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: