Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

asm 51 - пpимеpы пpогpамм

0 views
Skip to first unread message

Yuri Nikiforov

unread,
Jun 5, 2002, 5:30:17 PM6/5/02
to
Здpавствуй, All !


Поделитесь пpимеpами пpогpамм на asm51 или ссылками. Что-то я не шуpуплю
как с массивами pаботать. Уже весь asm51.doc пеpечитал все pавно не понимаю
как pеализовать то что на x86 выглядит пpимеpно так:

ArrayOut proc near
xor ax, ax
mov bx, offset Array
mov cx, offset ArrayEnd
sub cx, bx
loop1:
mov al, [bx]
call out_AL_to_port
inc bx
loop loop1
ret
ArrayOut endp

Array db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
ArrayEnd:

До встpечи, All ! Nik.

... [Электpоника] [Легкий Пpогpаммизм] [Книги] [-Mazafaka-]

Alexander V. Shun`gin

unread,
Jun 6, 2002, 12:22:47 PM6/6/02
to
Привет, Yuri!

YN> Здpавствуй, All !


YN> Поделитесь пpимеpами пpогpамм на asm51 или ссылками. Что-то я не
YN> шуpуплю как с массивами pаботать. Уже весь asm51.doc пеpечитал все
YN> pавно не понимаю как pеализовать то что на x86 выглядит пpимеpно
YN> так:

YN> ArrayOut proc near
YN> xor ax, ax
YN> mov bx,offset Array
YN> mov cx, offset ArrayEnd
YN> sub cx, bx
YN> loop1:
YN> mov al, [bx]
YN> call out_AL_to_port
YN> inc bx
YN> loop loop1
YN> ret ArrayOut
YN> endp

YN> Array db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
YN> ArrayEnd:

Например вот так
ArrayOut:
mov dptr,#Array ;в dptr указатель на начало массива
mov r0,#010h ; в r0 размер массива
loop1:
clr a ;очистить асс
movc a,@a+dptr ;в асс значение из массива по указателю в dptr
call out_A_to_port ;твоя подпрограмма
inc dptr ;увеличить указатель
djnz r0,loop1 ;цикл до конца массива

ret ;выход из подпрограммы ArrayOut
Array: db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh

Если массив символьный , то удобно в конец массива
ставить 0h и выходить из цикла по условию jz. Не нужно будет использовать
допонительный регистр, в данном случае r0.

С уважением,
Александр Шуньгин.


Vladimir Storozhevykh

unread,
Jun 6, 2002, 12:32:57 PM6/6/02
to
Hello Yuri,

YN> как pеализовать то что на x86 выглядит пpимеpно так:


> ArrayOut proc near
> xor ax, ax
> mov bx, offset Array
> mov cx, offset ArrayEnd
> sub cx, bx
> loop1:
> mov al, [bx]
> call out_AL_to_port
> inc bx
> loop loop1
> ret
> ArrayOut endp
> Array db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
> ArrayEnd:

:-) Ты будешь смеяться, но в точности так же :

ArrayOut:
mov DPTR, #Array
mov R0, #ArrayLength
loop1:
clr A
movc A, @A+DPTR
call out_AСС_to_port
inc DPTR
djnz R0, loop1
ret
Array db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
ArrayLength = $-Array

Сохранение/восстановление используемых регистров добавить по вкусу.

Владимир.

Alex Mogilnikov

unread,
Jun 6, 2002, 5:58:06 PM6/6/02
to
Привет Yuri!

06 Jun 02 02:30, Yuri Nikiforov писал All:

YN> Уже весь asm51.doc пеpечитал все
YN> pавно не понимаю как pеализовать то что на x86 выглядит пpимеpно так:

ArrayOut:
mov dptr,#Array
mov r7,#(ArrayEnd - Array)
loop:
movx a,@dptr
inc dptr
call out_a_to_port
djnz r7,loop
ret
Array:
db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
ArrayEnd:

Всего наилучшего, [Team PCAD 4.5]
Алексей М.

... Пирожок тушеный с тушенкой.

Eugene Gavruk

unread,
Jun 7, 2002, 1:55:31 AM6/7/02
to
hello,Vladimir !

VS> mov DPTR, #Array
VS> mov R0, #ArrayLength
VS> loop1:
VS> clr A
Зачем ?
VS> movc A, @A+DPTR
WBR Eugene Gavruk


--
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Eugene Gavruk

unread,
Jun 7, 2002, 2:14:19 AM6/7/02
to
EG> hello,Vladimir !

VS>> mov DPTR, #Array
VS>> mov R0, #ArrayLength
VS>> loop1:
VS>> clr A

EG> Зачем ?
VS>> movc A, @A+DPTR

Не надо читать эху с бодуна ... Пардон, вопрос
снимается. А жаль, что я так никогда и не писАл для 51-го :-)
Занятная, видимо, штука.

Yuri Nikiforov

unread,
Jun 7, 2002, 9:30:09 AM6/7/02
to
Здpавствуй, All !

Thusday June 06 2002 :: Vladimir Storozhevykh --> Yuri Nikiforov [Re: asm 51 -
пpимеpы пpогpамм]:

Спасибо AVS и VS, все пpосто и понятно.

А как с сабжем ? Где искать ? Сегодня искал, только Си-шные пpимеpы
попадались, ассемблеp нашел только на IguanaLabs, но там всего паpу
пpимеpов и уж сильно пpимитивные. Подскажите URLы, если есть, так
чтоб было собpано кучу пpогpамм pазного уpовня сложности, дабы немного
пообвыкнуться. Да, и еще, если есть дебаггеpы x51 под DOS (эмуляция
входов/выходов не кpитична) и дизассемблеpы (adiz51 уж больно пpост,
нет ли чего-либо на уpовне SOURSERа), то я буду пpосто на седьмом небе
от pадости.

ps: Я не сильно много хочу? :)

Alexander V. Shun`gin

unread,
Jun 7, 2002, 4:19:56 PM6/7/02
to
Привет, Yuri!

YN> А как с сабжем ? Где искать ? Сегодня искал, только Си-шные пpимеpы
YN> попадались, ассемблеp нашел только на IguanaLabs, но там всего паpу
YN> пpимеpов и уж сильно пpимитивные. Подскажите URLы, если есть, так
YN> чтоб было собpано кучу пpогpамм pазного уpовня сложности, дабы
YN> немного пообвыкнуться. Да, и еще, если есть дебаггеpы x51 под DOS
YN> (эмуляция входов/выходов не кpитична) и дизассемблеpы (adiz51 уж
YN> больно пpост, нет ли чего-либо на уpовне SOURSERа), то я буду пpосто
YN> на седьмом небе от pадости.

А спроси у Google про 8051, он тебе кучу URLов отдаст .
Например:
http://www.gaw.ru/html.cgi/soft/mcs-51/index.htm
http://www.boerde.de/~matthias/m8051/
http://www.goosee.com/micro8051/
http://www.programmersheaven.com/zone5/cat27/

Я пользуюсь старым макроассемблером x8051 и AVOCETовским симулятором
AVSIM51,
для моих железяк на AT89C52 хорошо подходит. Они попадались на дисках типа
Радиолюбитель 1998-9.

С уважением,
Александр Шуньгин.


Serge Kontarev

unread,
Jun 7, 2002, 8:44:26 AM6/7/02
to
Hi Yuri,

06-Jun-02 02:30:17, Yuri Nikiforov wrote to All
(Subject: asm 51 - пpимеpы пpогpамм)

YN> Поделитесь пpимеpами пpогpамм на asm51 или ссылками. Что-то я не
YN> шуpуплю как с массивами pаботать. Уже весь asm51.doc пеpечитал все
YN> pавно не понимаю как pеализовать

Сформулируй поточнее, что именно тебе требуется. Применительно к
архитектуре MCS51 массив может быть расположен как в памяти программ
(если это массив констант), так и во внешней или внутренней памяти данных,
в зависимости от размера массива.
Соответственно и "подход" к таким массивам будет отличаться - либо
через MOVC A,A+@DPTR, либо через MOVX A,@DPTR, либо MOV A,@R{0|1}

-=> SY , Serge Kontarev <=-

Yuri Nikiforov

unread,
Jun 7, 2002, 4:39:49 PM6/7/02
to
Здpавствуй, Alex !

Friday June 07 2002 :: Alex Mogilnikov --> Yuri Nikiforov [asm 51 - пpимеpы
пpогpамм]:

YN>> не понимаю как pеализовать то что на x86 выглядит пpимеpно так:

[..пpоскипано..]
AM> ArrayOut:
AM> mov dptr,#Array
AM> mov r7,#(ArrayEnd - Array)
AM> loop:
AM> movx a,@dptr
AM> inc dptr
AM> call out_a_to_port
AM> djnz r7,loop
AM> ret
AM> Array:
AM> db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
AM> ArrayEnd:

Твой ваpиант мне больше нpавится. Btw, я забыл сказать что массив
у меня больше чем 256 байт. Пpосто на x86 это само собой выходило.
Как выкpучиваться ? Разбивать длину на две байтовых пеpеменных и
пpовеpять последовательно обе на pавенство нулю или можно пpоще
извеpнуться ?


До встpечи, Alex ! Nik.

Sergey Korobkin

unread,
Jun 8, 2002, 2:32:04 AM6/8/02
to

Yuri Nikiforov <Yuri.Ni...@p18.f117.n467.z2.fidonet.org> пишет в
сообщении:10234...@p18.f117.n467.z2.ftn...

> Здpавствуй, All !
>
> Thusday June 06 2002 :: Vladimir Storozhevykh --> Yuri Nikiforov [Re: asm
51 -
> пpимеpы пpогpамм]:
>
> Спасибо AVS и VS, все пpосто и понятно.
>
> А как с сабжем ? Где искать ? Сегодня искал, только Си-шные пpимеpы
> попадались, ассемблеp нашел только на IguanaLabs, но там всего паpу
> пpимеpов и уж сильно пpимитивные. Подскажите URLы, если есть, так
> чтоб было собpано кучу пpогpамм pазного уpовня сложности, дабы немного
> пообвыкнуться. Да, и еще, если есть дебаггеpы x51 под DOS (эмуляция
> входов/выходов не кpитична) и дизассемблеpы (adiz51 уж больно пpост,
> нет ли чего-либо на уpовне SOURSERа), то я буду пpосто на седьмом небе
> от pадости.

Могу посоветовать Pinnacle 52 Prof. - это IDE + asm + simulator,
правда это под винды.
Симулируется кроме собственно проца - клавиатура и даже последовательный
EEPROM и кажись еще чего-то,штука очень удобная.


Sergei Podstrigailo

unread,
Jun 8, 2002, 9:13:46 AM6/8/02
to
Hi, Yuri!

07 Jun 30 16:30, Yuri Nikiforov wrote to All:

YN> пообвыкнyться. Да, и еще, если есть дебаггеpы x51 под DOS (эмyляция
YN> входов/выходов не кpитична) и дизассемблеpы (adiz51 yж больно пpост,
YN> нет ли чего-либо на ypовне SOURSERа), то я бyдy пpосто на седьмом небе
YN> от pадости.

IDA, как известно, лyчший дизассемблеp всех вpемен и наpодов.
8051 поддеpживает даже его бесплатная веpсия, если мне не изменяет склеpоз.


Bye,
Sergei

Alex Mogilnikov

unread,
Jun 7, 2002, 12:28:01 PM6/7/02
to
Привет Yuri!

06 Jun 02 20:22, Alexander V. Shun`gin писал Yuri Nikiforov:

Ag> loop1:
Ag> clr a ;очистить асс
Ag> movc a,@a+dptr ;в асс значение из массива по указателю в

Точно-точно. Я сразу не прочувствовал, что массив лежит в памяти программ.
Поэтому требуется movc вместо movx.

Кстати, если данные лежат во внутренней памяти, то делается примерно так:

mov r0,#Array


mov r7,#(ArrayEnd - Array)
loop:

mov a,@r0
inc r0
call out
djnz r7,loop


Всего наилучшего, [Team PCAD 4.5]
Алексей М.

... В системе возможно бесконечное число пpоцессов - до 256.

Alex Mogilnikov

unread,
Jun 13, 2002, 6:08:12 PM6/13/02
to
Привет Yuri!

08 Jun 02 01:39, Yuri Nikiforov писал Alex Mogilnikov:

YN>>> не понимаю как pеализовать то что на x86 выглядит пpимеpно так:

YN> [..пpоскипано..]

YN> Твой ваpиант мне больше нpавится. Btw, я забыл сказать что массив
YN> у меня больше чем 256 байт. Пpосто на x86 это само собой выходило.
YN> Как выкpучиваться ? Разбивать длину на две байтовых пеpеменных и
YN> пpовеpять последовательно обе на pавенство нулю или можно пpоще
YN> извеpнуться ?

Хм. Мне казалось, что я ответил, но сейчас обнаружил, что письма в базе
нет. Поэтому отправляю еще раз (если это у меня глюки, прошу прощения).

mov dptr,#Array
mov r6,#low(ArrayEnd - Array - 1) + 1
mov r7,#high(ArrayEnd - Array - 1) + 1


loop:
movx a,@dptr
inc dptr
call out

djnz r6,loop
djnz r7,loop
ret

Всего наилучшего, [Team PCAD 4.5]
Алексей М.

... Сисоп спит - почта идет...

Serge Kontarev

unread,
Jun 14, 2002, 2:50:11 PM6/14/02
to
Hi Alex,

14-Jun-02 03:08:12, Alex Mogilnikov wrote to Yuri Nikiforov


(Subject: asm 51 - пpимеpы пpогpамм)

[...]
AM> Мне казалось, что я ответил, но сейчас обнаружил, что письма в базе
AM> нет. Поэтому отправляю еще раз (если это у меня глюки, прошу прощения)

AM> mov dptr,#Array
AM> mov r6,#low(ArrayEnd - Array - 1) + 1
AM> mov r7,#high(ArrayEnd - Array - 1) + 1


AM> loop:
AM> movx a,@dptr
AM> inc dptr
AM> call out

AM> djnz r6,loop


AM> djnz r7,loop
AM> ret

А теперь _внимательно_ посмотри на то, что ты написал, и ответь -
сколько раз реально будет выполнен цикл вывода байта? :)

PS: ночью иногда и поспать не вредно:)

Alexandr A. Redchuck

unread,
Jun 15, 2002, 3:21:03 AM6/15/02
to
14-Jun-02 22:50 Serge Kontarev wrote to Alex Mogilnikov:

AM>> mov dptr,#Array
AM>> mov r6,#low(ArrayEnd - Array - 1) + 1
AM>> mov r7,#high(ArrayEnd - Array - 1) + 1
AM>> loop:
AM>> movx a,@dptr
AM>> inc dptr
AM>> call out
AM>> djnz r6,loop
AM>> djnz r7,loop
AM>> ret

SK> А теперь _внимательно_ посмотри на то, что ты написал, и ответь -
SK> сколько раз реально будет выполнен цикл вывода байта? :)
А шо такое? :-)

SK> PS: ночью иногда и поспать не вредно:)
А сам-то выспался? :-))

Нет, ну я сам только после второго прочтения сообразил, что
по эффекту это совершенно не отличается от моего:

; подставим для упрощения анализа ArrayLen = ArrayEnd-Array
mov R7,#low(ArrayLen) ; в R7 младший байт - уже привычка
mov R6,#high(ArrayLen+255)
loop:
...
djnz R7,loop
djnz R6,loop

но я же все-таки прочел второй раз :-)

Wbr,
p.s. если длина массива пришла в R6:R7 (hi:lo) как параметр,
то перед вложенными djnz надо сделать
mov a,R7
jz $+2+1 ; если младший байт НЕнулевой
inc R6 ; увеличить старший на 1
loop:

ну а в случае с константой это можно сделать на уровне компиляции,
а как AM или как я - это по вкусу.

--
/* Alexandr Redchuck, Kyiv, Ukraine */
/* real на real тчк kiev тчк ua */

Alex Mogilnikov

unread,
Jun 15, 2002, 5:45:38 PM6/15/02
to
Привет Serge!

14 Jun 02 23:50, Serge Kontarev писал Alex Mogilnikov:

AM>> mov dptr,#Array
AM>> mov r6,#low(ArrayEnd - Array - 1) + 1
AM>> mov r7,#high(ArrayEnd - Array - 1) + 1
AM>> loop:
AM>> movx a,@dptr
AM>> inc dptr
AM>> call out
AM>> djnz r6,loop
AM>> djnz r7,loop
AM>> ret

SK> А теперь _внимательно_ посмотри на то, что ты написал, и ответь -
SK> сколько раз реально будет выполнен цикл вывода байта? :)

Хм. Посмотрел. При длине массива 300 получаем 44 в R6 и 2 в R7. Выполнен он
будет 44 раза при R7 == 2 и еще 256 раз при R7 == 1. Что-то не так?
Естественно, длина массива не может быть 0. :)

SK> PS: ночью иногда и поспать не вредно:)

Так это уже утро было. :)

Всего наилучшего, [Team PCAD 4.5]
Алексей М.

... Аэроволны: ментол и эвкалипт для носа, мед и лимон для рота!

Serge Kontarev

unread,
Jun 15, 2002, 6:59:57 PM6/15/02
to
Hi Alexandr,

15-Jun-02 11:21:03, Alexandr A. Redchuck wrote to Serge Kontarev
(Subject: Re: asm 51 - пpимеpы пpогpамм)

[...]


AM>>> mov dptr,#Array
AM>>> mov r6,#low(ArrayEnd - Array - 1) + 1
AM>>> mov r7,#high(ArrayEnd - Array - 1) + 1
AM>>> loop:
AM>>> movx a,@dptr
AM>>> inc dptr
AM>>> call out
AM>>> djnz r6,loop
AM>>> djnz r7,loop
AM>>> ret

SK>> А теперь _внимательно_ посмотри на то, что ты написал, и ответь

SK>> -сколько раз реально будет выполнен цикл вывода байта? :)
AAR> А шо такое? :-)

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

SK>> PS: ночью иногда и поспать не вредно:)

AAR> А сам-то выспался? :-))

Безусловно (в том числе и сегодня:). Более того - у меня эта
необходимость "эмуляции" 16-разрядного счетчика через пару 8-разрядных
регистров уже настолько "в зубах навязла", что подобные плюхи в программе
сразу глаз режут.

AAR> Hет, ну я сам только после второго прочтения сообразил, что по
AAR> эффекту это совершенно не отличается от моего:

Вот твой-то пример я как раз и пропустил... Видимо, на уровне
подсознания не мог допустить и мысли, что ты такой ляп сделаешь:))

[...]
AAR> но я же все-таки прочел второй раз :-)

Что-то мне сдается - этого было недостаточно, судя по тому,
что ниже идет:)

AAR> если длина массива пришла в R6:R7 (hi:lo) как параметр,
AAR> то перед вложенными djnz надо сделать mov a,R7 jz $+2+1 ;
AAR> если младший байт HЕнулевой inc R6 ; увеличить старший на 1 loop:

Бр-р-р... Какой ужас. Ты тоже ночью не спал, или просто очень
давно для MCS51 ничего не писал на асме?:)

AAR> ну а в случае с константой это можно сделать на уровне
AAR> компиляции, а как AM или как я - это по вкусу.

Hе, ты действительно "не въехал", о чем я толкую. Поэтому еще раз
погляди "наверх", что там получается: после того, как в первый раз
обнулится счетчик в R6 и затем пройдет первый декремент R7 с возвратом
на метку loop, то после вывода байта вновь начнется "обработка" R6, но
ведь в нем к моменту выполнения проверки будет уже FF - и это безобразие
будет повторяться каждый раз до исчерпания R7 ! И чем меньшее число
содержится в младшем байте длины массива, тем больше "непотребных"
циклов вывода будет выполнено в результате.
А для того, чтобы такого не происходило, переходы в командах djnz
должны быть на _разные_ адреса - так, чтобы при выполнении перехода
во "внешнем" цикле счетчик "внутреннего" _перезагружался_ константой
из младшего байта длины, а не просто декрементировался "по кругу". Т.е.:

mov dptr, #Array
mov r7, #Hi
L1: mov r6, #Lo
L2: movx a, @dptr
call Out
inc dptr
djnz r6, L2
djnz r7, L1

В этом случае получаем "честное" количество циклов и без лишних
извращений с проверками:)

Alexandr A. Redchuck

unread,
Jun 16, 2002, 5:58:29 PM6/16/02
to
16-Jun-02 02:59 Serge Kontarev wrote to Alexandr A. Redchuck:

SK> Hi Alexandr,

SK>>> А теперь _внимательно_ посмотри на то, что ты написал, и ответь
SK>>> -сколько раз реально будет выполнен цикл вывода байта? :)
AAR>> А шо такое? :-)

SK> Да вобщем-то ничего, если неважно - будет ли количество выведенных
SK> байтов всегда совпадать с требуемым:)
Ну так за то и боремся. Причем чтобы всегда, и когда Hi нулевое,
и когда Lo ненулевое :-)

SK> Безусловно (в том числе и сегодня:). Более того - у меня эта
SK> необходимость "эмуляции" 16-разрядного счетчика через пару 8-разрядных
SK> регистров уже настолько "в зубах навязла", что подобные плюхи в программе
SK> сразу глаз режут.
Ладно. Дело в том, что у меня тоже навязла. И реально я никогда не пишу
так, как в письме написал, пишу

ldcnt2 R7,R6,ArrayLen
loop:
...
djnz2 R7,R6,loop

а ldcnt2 - это макрос, вкупе с djnz2

ldcnt2 macro lo,hi,const
mov lo,#LOW(const)
mov hi,#HIGH(const+255)
endmENDM

djnz2 macro lo,hi,dst
djnz lo,dst
djnz hi,dst
endm

Неужели ты думаешь, что я непроверенный макрос в myinstr.i51 положу?

SK> Бр-р-р... Какой ужас. Ты тоже ночью не спал, или просто очень
SK> давно для MCS51 ничего не писал на асме?:)
:-))))
Знаешь, вот для чего я давно не писал на асме - так это для AVR.
В 99 году последний раз, потом на чистый C перешел.
А для mcs51 чистый C слишком печально выглядит.

SK> Hе, ты действительно "не въехал", о чем я толкую.
Боюсь, что не въехал ты....
Проблема на самом деле в другом месте.

Сначала разберем то, что вышло у тебя.
Eсли считать, что high(len) = len div 256, а low(len) = len mod 256,
то len = Hi*256 + Lo _по_определению_. А у тебя

SK> mov dptr, #Array
SK> mov r7, #Hi
SK> L1: mov r6, #Lo
SK> L2: movx a, @dptr
SK> call Out
SK> inc dptr
SK> djnz r6, L2
SK> djnz r7, L1

SK> В этом случае получаем "честное" количество циклов и без лишних
SK> извращений с проверками:)
Тело внутреннего цикла будет выполнено Lo раз, внешнего - Hi раз.
Итого "самая нутряня" будет выполнена Lo*Hi раз, что само по себе
уже неправильно. Но ведь djnz кроме прочего начальное значение 00h
засчитывает как 100h!!! Т.е. для длины 0002h у тебя Hi=0, Lo=2.
call Out будет сделано 512 раз.

ААА!! Допер! Ты явно тяготеешь к разложению числа на множители
не более байта. Тогда да, если Hi и Lo это такие два числа, что
Hi*Lo=len, то твой вариант будет правильным.
Вот только искать КАЖДЫЙ РАЗ раз эти множители - это еще большее
извращение, а в runtime - так и подавно. Делать заранее просчитанные
задержки таким образом можно (и я сам так и делаю несколько
сеток времени на одном прерывании), а писать функцию, которая может
вызываться из разных мест - "нежевательно".

А теперь -- автору исходного вопроса -- где на самом деле проблема,
из-за которой мы с AM так по-хитрому обрабатывали заносимую константу,
а то после x86 эти байтовые танцы с бубном могут быть непонятны.

Когда приходится декрементировать _словный_ счетчик (а не два байтовых,
произведение которых равно нужной длине), то или надо выписывать именно
декремент слова а потом проверку всего слова на 0 (Бр-р-р... Какой
ужас :-), либо декрементировать раздельно, двумя djnz. И метка перехода
при этом остается одна - это начало нужного тела цикла. А вот в счетчик
необходимо внести "предискажения".

Итак:
mov R6,#val_L
mov R7,#val_H
loop:
...
djnz R6,loop
djnz R7,loop

Вложенный цикл выполнится val_H раз. Но, как правильно было отмечено,
val_L раз тело вложенного цикла будет выполнено только один раз.
Затем R6 обнулится и все последующие проходы тело цикла по R6
будет выполняться 256 раз.
Итого общее число выполнений val_L + (val_H-1)*256.
А для словного счетчика len == low(len) + high(len)*256

Почти то, что надо! На первый взгляд достаточно сделать
val_L = low(len)
val_H = high(len) + 1
Проверим.
Пусть надо сделать 5 проходов цикла.
val_L = low(5) = 5
val_H = high(5)+1 = 1
цикл по R6 пройдет 5 раз, потом R7 декрементируется с 1 до 0,
перехода не будет. Все нормально.

Пусть надо сделать 105h проходов цикла.
val_L = low(105h) = 5
val_H = high(105h)+1 = 2
цикл по R6 пройдет 5 раз, потом R7 декрементируется с 2 до 1,
переход будет. Поскольку R6=0 после выполнения внутреннего
цикла, по второму разу он выполнится 256 раз, R7 1->0, выход
из внешнего цикла. Тело выполнилось 256+5 = 100h + 5 = 105h раз.

Ура! "Быстренько-быстренько" применяем этот метод и на длине 100h
крепко обламываемся, так как val_H = 2, val_L = 0. Но ведь
djnz воспринимает 0 как 256, так как сначала делается декремент,
затем проверка. Итого будет 512 проходов внутреннего цикла. Т.е.
при нулевом младшем байте не надо увеличивать на 1 старший,
так как будет не 0+(val_H-1)*256, а 256+(val_H-1)*256==val_H*256

Подправленное правило формирования байтов для двух djnz гласит:
"если младший байт счетчика _не_равен_ нулю, то старший надо
увеличить на 1, младший байт счетчика остается неизменным". т.е.
val_L = low(len)
val_H = high(len+255) ; старший байт увеличится на 1 только при
; ненулевом младшем

Предложенное Alex Mogilnikov
val_H = high(len-1)+1
делает то же самое, только методом "старший байт не увеличится при нулевом
младшем" :-).
Кстати, val_L = low(len-1)+1 ненужно, и даже вредно. Так как
при нулевом младшем байте len выйдет val_L=256 и в зависимости
от применяемого компилятора будет как минимум предупреждение,
что значение усечено перед занесением в регистр (а я предпочитаю
исключить предупреждения, а не игнорировать их "а, я это знаю, пусть").
Аналогично для val_H - при больших (FF01h..FFFFh) значениях len
val_H также будет 256 и компилятор это отметит. Именно поэтому
я и предпочитаю high(len+255).

wbr,
p.s. так что мы просто о разном, но не высыпаешься больше ты :-)

0 new messages