реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Вопрос к ассемблерщикам, Автоматическая растановка адресов
SasaVitebsk
сообщение Mar 9 2009, 21:07
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Maik-vs @ Mar 8 2009, 19:17) *
Какое странное и невнятное обсуждение. То есть некоторые обвиняют ассемблер в его "бедности", не понимании структур и т.д. А я вот видел множество обсуждений сишников: то как объявить переменную в нужной памяти, то как проинвертировать бит в порту то ещё что-нибудь, что у ассемблерщика вызовет недоумённую улыбку.
Такой язык. И можно написать кучу макросов каждому на свой вкус, в том числе и для доступа к структурам. К Вашим структурам. А вообще-то конечно, кому что - есть и VBA или вот ЛИСП интересный язык smile.gif

Ещё раз отмечаю. Само написание проги на асме, как правило занимает даже меньше времени (особенно для млких проектов) чем на асме. Я имею ввиду грамотное написание там и там. Но ... сопровождение и развитие проекта на Си ... на порядок быстрее и комфортнее. На порядок это в 10 раз. И это не для красного словца, а это приблизительно мои оценки затрат.

По обсуждаемой теме всётаки на мой взгляд правильнее автоматическое выделение памяти. А не относительное со смещением.
То есть я не вижу преимуществ (Зато кучу недостатков) в конструкции типа:
Код
.equ    SRAM_NEXT_1          = SRAM_START + 1;
.equ    SRAM_NEXT_2          = SRAM_NEXT_1 + 10;
.equ    SRAM_NEXT_3          = SRAM_NEXT_2 + 100;

На мой взгляд правильнее конструкция типа:
Код
            .dseg
    .org    SRAM_START_ADR
SRAM_START:     .byte     1
SRAM_NEXT_1:   .byte     10
SRAM_NEXT_2:   .byte     100
SRAM_NEXT_2:


Причём 1,10,100 я бы задал через "equ".

Точно также я работаю и со структурами.
Например:
Код
; Структура X(i-1), Y(i-1)*2, Y(i-2)*2, Z(i-1)*2, Z(i-2)*2
MADC:        .byte    6*9    ; Измерения по каналам
MADC_SR:                ; Усреднённое значение измерения по каналам
MADC_0:        .byte    1    ; Усреднённое значение измерения канала 0
MADC_1:        .byte    1    ; Усреднённое значение измерения канала 1
MADC_2:        .byte    1    ; Усреднённое значение измерения канала 2
MADC_3:        .byte    1    ; Усреднённое значение измерения канала 3
MADC_4:        .byte    1    ; Усреднённое значение измерения канала 4
MADC_5:        .byte    1    ; Усреднённое значение измерения канала 5
MADC_SRx2:    .byte    6    ; Усреднённое значение измерения по каналам после второго усреднения
MStrel:        .byte    12    ; Значение для стрелки в шагах
MTStrel:                ; Текущее значение для стрелки в шагах
MTStr0:        .byte    2
MTStr1:        .byte    2
MTStr2:        .byte    2
MTStr3:        .byte    2
MTStr4:        .byte    2
MTStr5:        .byte    2

Для IAR ассемблера, естественно, используется принцип размещения структур Си. Причём очень органично всё получается.

Приведу пример:
Вот структура в Си
Код
struct
{
uint8_t    OutBuf[32];                                    // 0
uint8_t    *HeadOutBuf,*EndOutBuf;                        // +32 +34
uint8_t    AddrWake;                                    // +36
uint8_t    ComAnswerWake,                                // +37
            ParComAnswer,                                // +38
            Com485;                                        // +39
uint16_t    LenPack485;                                    // +40  RS232. Длина    передаваемого пакета данных
uint8_t    *EndInBuf;                                    // +42  RS232. Указатель на конец принятых данных
struct
{
   uint8_t    Answ485     : 1,                            // Выдать ответ по rs485
            Esc485      : 1,                            // Пришёл код FESC с RS485
            RcvCompl    : 1,                            // Разрешить исполнение    команд
            Ldr            : 1,                            // Разрешить загрузку ПО
            NoEndPacket    : 1;                            // Пакет незавершён
} Flag;                                                // +44
}  volatile Out485;

Вот её объявление на ASMе
Код
EXTERN    Out485

#define        HeadOutBuf        32                            // +32
#define        EndOutBuf        34                            // +34
#define        AddrWake        36                            // +36
#define        ComAnswerWake    37                            // +37
#define        ParComAnswer    38                            // +38
#define        Com485            39                            // +39
#define        LenPack485        40                            // +40  RS232. Длина    передаваемого пакета данных 16
#define        EndInBuf        42                            // смещение +41  RS232. Указатель на конец принятых данных
#define        FlagS            44                            // +43 Признаки
#define        Answ485            0                            // Бит 0 Выдать ответ по rs485
#define        Esc485            1                            // Бит 1 Пришёл код FESC с RS485
#define        RcvCompl        2                            // Бит 2 Разрешить исполнение команд
#define        Ldr                3                            // Бит 3 Разрешить загрузку ПО
#define        NoEndPacket        4                            // Бит 4 Пакет незавершён


Вот пример обращения к полю
Код
        ldd        crc485,Z+AddrWake            // AddrWake
        std        Z+HeadOutBuf,ZL                // HeadOutBuf
        std        Z+HeadOutBuf+1,ZH            // HeadOutBuf+1
        ldi        data485,FEND
Go to the top of the page
 
+Quote Post
adc
сообщение Mar 10 2009, 07:58
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 409
Регистрация: 29-10-07
Пользователь №: 31 836



Цитата(SasaVitebsk @ Mar 10 2009, 00:07) *
Само написание проги на асме, как правило занимает даже меньше времени (особенно для млких проектов) чем на асме.

"Золотые слова Юрий Бенедиктович и человек ты золотой,не бережёшь ты себя,отдохнуть тебе надо." (НР) rolleyes.gif


--------------------
Умный программист пишет тупым кодом гениальные вещи, а не наоборот...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 10 2009, 08:26
Сообщение #18


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(CDT @ Mar 9 2009, 09:15) *
Что ж так нервничать. Можно было бы и предложить правильное решение.
Я  не нервный. Более того, в предыдущем посте Вы совершенно логично мыслили. Беда в том, что AVRASM хоть 1 хоть 2 хоть пицот - дебильные асмы.
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение Mar 10 2009, 08:27
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101



Цитата(SasaVitebsk @ Mar 10 2009, 00:07) *
Ещё раз отмечаю. Само написание проги на асме, как правило занимает даже меньше времени (особенно для млких проектов) чем на асме. Я имею ввиду грамотное написание там и там. Но ... сопровождение и развитие проекта на Си ... на порядок быстрее и комфортнее. На порядок это в 10 раз. И это не для красного словца, а это приблизительно мои оценки затрат.

Что такое "на порядок", я знаюsmile.gif.
Порядок/не порядок - всё зависит от правильного оформления. Я вначале (как многие, думаю) не понимал нафига эта куча комментариев, правила поименования и т.д. Пришло со временем.
Цитата(SasaVitebsk @ Mar 10 2009, 00:07) *
По обсуждаемой теме всётаки на мой взгляд правильнее автоматическое выделение памяти. А не относительное со смещением.
То есть я не вижу преимуществ (Зато кучу недостатков) в конструкции типа:
Код
.equ    SRAM_NEXT_1          = SRAM_START + 1;
.equ    SRAM_NEXT_2          = SRAM_NEXT_1 + 10;
.equ    SRAM_NEXT_3          = SRAM_NEXT_2 + 100;

На мой взгляд правильнее конструкция типа:
Код
            .dseg
    .org    SRAM_START_ADR
SRAM_START:     .byte     1
SRAM_NEXT_1:   .byte     10
SRAM_NEXT_2:   .byte     100
SRAM_NEXT_2:


Причём 1,10,100 я бы задал через "equ".

+100

А вот это я не понял, зачем:
Цитата(SasaVitebsk @ Mar 10 2009, 00:07) *
Вот её объявление на ASMе
Код
EXTERN    Out485

#define        HeadOutBuf        32                            // +32
#define        EndOutBuf        34                            // +34
#define        AddrWake        36                            // +36
#define        ComAnswerWake    37                            // +37
#define        ParComAnswer    38                            // +38
#define        Com485            39                            // +39
...


Если задана структура
Код
OutBuf:           byte 32;                     // 0
HeadOutBuf:    byte 2
EndOutBuf:      byte 2                        // +32 +34
AddrWake:       byte 2                        // +36
ComAnswerWake:     byte 1                 // +37
ParComAnswer:    byte 1                     // +38
Com485:          byte 1                        // +39
и т.д.

Я пишу
Код
               LD2      Z,OutBuf        // LD2 макрос 2-байтовой загрузки
               std      Z+  AddrWake-OutBuf

и не надо всех этих дефайнов.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 10 2009, 17:34
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Maik-vs @ Mar 10 2009, 12:27) *
А вот это я не понял, зачем:
....
и не надо всех этих дефайнов.

То что вы написали - понятно. Согласен.
Просто в моём примере - структура объявлена на Си. В файле ASMа, я её объявляю внешней. Поэтому не могу размещать заново. А дефайнами объявляю смещение полей.

Ну а асмовое обращение - фактически именное получается. Наглядно на мой взгляд.

Можно, наверное, наоборот. Размещать на асме как вы, а в Си-шном модуле объявлять её внешней. Тогда будет как в вашем примере. У меня просто порядок написания был "от Си". smile.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 10 2009, 17:56
Сообщение #21


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(galjoen @ Mar 10 2009, 18:55) *
Пусть они там говорят, что 10 раз всё это исправили. Не верю я им больше. И не вижу смысла в риске.

Если рассматривать под таким углом (я не ярый сторонник Си), то получается как-бы такое: в случае асма между программером и железом кроме примитивной программы нет никаких посредников. В случае Си - есть. Отсюда появились всякие MISRA и прочие "нематериальные сущности"

Цитата(SasaVitebsk @ Mar 10 2009, 20:34) *
Можно, наверное, наоборот. Размещать на асме как вы, а в Си-шном модуле объявлять её внешней. Тогда будет как в вашем примере. У меня просто порядок написания был "от Си". smile.gif

На примере WinAVR: в одном хедере содержится описание полей для гнутого асма и typedef

Код
#ifndef __ASSEMBLER__
typedef struct
{
 uint8_t field1;
 unsigned flag1:1;
unsigned flag2:1;
unsigned enu:6;
} packet_t

volatile packet_t pack;

#else

#define packet_field1 0
#define packet_flag1 0x01
#define packet_flag2 0x02
#define packet_enu_msk 0xfc
#define packet_enu_offset 0x02
#define flags 0x01
#define sz_packet 2
.extern pack

#endif


 
Go to the top of the page
 
+Quote Post
yod
сообщение Mar 11 2009, 08:46
Сообщение #22


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 20-10-06
Пользователь №: 21 500



Цитата(galjoen @ Mar 8 2009, 13:45) *
...
Код
.MACRO TAB_Z
    subi    ZL,low(-low(@0)); получение
    sbc    ZH,ZH; адреса в
    subi    ZH,low(-high((@0)-1))-1; таблице
.ENDMACRO

...


Спасибо за интересный ход, ибо ситуация действительно частая.
Сам долгое время работал с ассемблером, но в последнее время, ввиду объемности проектов, пользуюсь связкой eclipse+gcc (последняя сборка от Klen'а), однако по-прежнему, в критических местах люблю подписать на асме.

попытка внедрить этот код увенчалась провалом - никак компилятор сожрать не может такую конструкцию
Код
        "subi    %A[queue],-lo8(%[heap])"        "\n\t" /*получение*/
        "sbc    %B[queue],%B[queue]"            "\n\t" /*адреса в*/
        "subi    %B[queue],lo8(-hi8(%[heap]-1)-1)"     "\n\t" /*таблице*/

ошибки выдает дурные
C:\DOCUME~1\electro\LOCALS~1\Temp/ccX8y7d0.s:1163: Error: garbage at end of line
C:\DOCUME~1\electro\LOCALS~1\Temp/ccX8y7d0.s:1165: Error: `)' required
C:\DOCUME~1\electro\LOCALS~1\Temp/ccX8y7d0.s:1165: Error: garbage at end of line
судя по всему не может выполнять арифметические операции потому как простейшие конструкции типа
Код
        "subi    %A[queue],lo8(%[heap])"        "\n\t" /*получение*/
        "subi    %B[queue],hi8(%[heap])"     "\n\t" /*таблице*/
или
        "subi    %A[queue],%A[heap]"        "\n\t" /*получение*/
        "subi    %B[queue],%B[heap]"     "\n\t" /*таблице*/

скармливаются успешно
чуть более подробный код для введения в курс дела:
CODE

struct {
uint8_t Put;
uint8_t Get;
MPACKET* Container[CONST_FREEMEM_QUEUE_SIZE];
}QueueFreePacket;

исходный код на С
void QueuePut(TQUEUE* Queue,MPACKET* Packet){
if (Packet){
if(Queue){
//uint8_t tmp=Queue->Put + 1;
//if(tmp==CONST_QUEUE_SIZE)tmp=0;

uint8_t tmp=Queue->Put - (CONST_QUEUE_SIZE-1);
if(tmp)tmp+=CONST_QUEUE_SIZE;

if (tmp!=Queue->Get){
Queue->Container[Queue->Put]=Packet;
Queue->Put=tmp;
return;
}
}
QueueFreePacket.Container[QueueFreePacket.Put++]=Packet;
if (QueueFreePacket.Put==CONST_FREEMEM_QUEUE_SIZE) QueueFreePacket.Put=0;
}
}

часть асемблерной вставки для помещения пакета в очередь свободных пакетов
__asm__ __volatile__(
.....
"pkt_move_to_heap%=:" "\n\t"
"lds %A[queue],%[heap]" "\n\t"
"mov %[tmp],%A[queue]" "\n\t"
"subi %A[queue],-lo8(%[heap])" "\n\t" /*получение*/
"sbc %B[queue],%B[queue]" "\n\t" /*адреса в*/
"subi %B[queue],lo8(-hi8(%[heap]-1)-1)" "\n\t" /*таблице*/
"st %a[queue]+,%A[pkt]" "\n\t"
"st %a[queue],%B[pkt]" "\n\t"
"subi %[tmp],(%[heap_size]-1)<<1" "\n\t"
"cpse %[tmp],__zero_reg__" "\n\t"
"subi %[tmp],-(%[size]<<1)" "\n\t"
"sts %[heap],%[tmp]" "\n\t"


"exit%=:" "\n\t"
: "=&d"(tmp)
: [queue]"b"(Queue),[pkt]"w"(Packet),[tmp]"r"(tmp),[size]"M"(CONST_QUEUE_SIZE),[heap]"m"(QueueFreePacket),[heap_size]"M"(CONST_FREEMEM_QUEUE_SIZE)
: "1","memory"
);

Подскажите как коректно переписать это место ассемблерной вставки laughing.gif

Сообщение отредактировал yod - Mar 11 2009, 08:49
Go to the top of the page
 
+Quote Post
galjoen
сообщение Mar 11 2009, 14:53
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(yod @ Mar 11 2009, 11:46) *
...
Подскажите как коректно переписать это место ассемблерной вставки laughing.gif

Я так понимаю, что отрицательное число от "lo8" будет уже не lo8, а int. Т.е. -lo8 преобразуется в int, и вот в этом ошибка, как мне кажется (хотя при чём там мусор?). Поэтому я на асме от него low беру. Хотя некоторые асмы и так понимают. А в вашем случае, чтоб компилятору умничать не позволять, лучше наверное 0xFF& везде делать. Ещё рекомендую на скобках не экономить. Компиляторы они ведь очень умничать любят... Хотя и пробовать нужно конечно. А у меня негде. Т.е. что-то типа такого я написал бы.
Код
        "subi    %A[queue],(0xFF&(0-(0xFF&(%[heap]))))"        "\n\t" /*получение*/
        "sbc    %B[queue],%B[queue]"            "\n\t" /*адреса в*/
        "subi    %B[queue],(0xFF&(0-(0xFF&((%[heap]-1)>>8))-1))"     "\n\t" /*таблице*/

А м.б и ещё раз lo8 поставить в первой и последней строке придётcя. Но вообще, из меня сейчас писатель на Си для авр никакой...
Go to the top of the page
 
+Quote Post
yod
сообщение Mar 11 2009, 18:52
Сообщение #24


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 20-10-06
Пользователь №: 21 500



гхм, спасибо, попробовал, не вышло.
теперь пишет иную ошибку:
C:\DOCUME~1\electro\LOCALS~1\Temp/ccTCdAe5.s: Assembler messages:
C:\DOCUME~1\electro\LOCALS~1\Temp/ccTCdAe5.s:1163: Error: invalid sections for operation on `L0' and `QueueFreePacket'
из чего, вероятно, можно сделать вывод, что компилятор пытается "с ассемблировать" код раньше чем генерирует адрес структуры
Go to the top of the page
 
+Quote Post
galjoen
сообщение Mar 11 2009, 19:12
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(yod @ Mar 11 2009, 21:52) *
гхм, спасибо, попробовал, не вышло.
теперь пишет иную ошибку:
C:\DOCUME~1\electro\LOCALS~1\Temp/ccTCdAe5.s: Assembler messages:
C:\DOCUME~1\electro\LOCALS~1\Temp/ccTCdAe5.s:1163: Error: invalid sections for operation on `L0' and `QueueFreePacket'
из чего, вероятно, можно сделать вывод, что компилятор пытается "с ассемблировать" код раньше чем генерирует адрес структуры

М.б. и так. А откуда компилятор `L0' взял?
Но хотя тогда почему:
Код
        "subi    %A[queue],lo8(%[heap])"        "\n\t" /*получение*/
        "subi    %B[queue],hi8(%[heap])"     "\n\t" /*таблице*/
или
        "subi    %A[queue],%A[heap]"        "\n\t" /*получение*/
        "subi    %B[queue],%B[heap]"     "\n\t" /*таблице*/

скармливаются успешно
Они в том-же месте размещены были? А если постепенно усложнять, то в какой момент компилятор ругаться начнёт?
А м.б. два #define, предварительно размещённые, спасут?
Go to the top of the page
 
+Quote Post
yod
сообщение Mar 12 2009, 02:02
Сообщение #26


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 20-10-06
Пользователь №: 21 500



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

Сообщение отредактировал yod - Mar 12 2009, 02:02
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 12 2009, 02:34
Сообщение #27


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(yod @ Mar 11 2009, 11:46) *
Подскажите как коректно переписать это место ассемблерной вставки


Не пользуйтесь идиотскими фичами, и счастие да пребудет с Вами smile.gif 
Go to the top of the page
 
+Quote Post
ReAl
сообщение Mar 14 2009, 10:02
Сообщение #28


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(galjoen @ Mar 8 2009, 09:45) *
А массив не выровнен, т.е. может переходить через границу 256. Т.е. старший байт адреса может отличаться на 1. Стандартный способ это 4 такта. Но есть способ лучше. Я написал макро, и всегда и использую.
Код
.MACRO TAB_Z
    subi    ZL,low(-low(@0)); получение
    sbc    ZH,ZH; адреса в
    subi    ZH,low(-high((@0)-1))-1; таблице
.ENDMACRO

Перед вызовом смещение д.б. в ZL. Параметр в этой макрокоманде - адрес начала таблицы. В байтах если это данные, в словах если это таблица переходов.
Такие макрокоманды у меня обычно и для Y и для X описаны. Рекомендую...

Цитата(Сергей Борщ @ Mar 8 2009, 11:52) *
Красиво! Спасибо, записал на корочку.

Цитата(_Pasha @ Mar 8 2009, 12:04) *
Респект! А говорят, что про асм и AVR уже все известно...

А-а-а-а!!!! Мужики, что вы делаете? Я на собственной шкуре убедился в реальности тех психологических экспериментов, когда садят человека в компании, как он думает, таких же испытуемых, задают всем несколько вопросов, а потом показывают белый листик и спрашивают "какой цвет?" все говорят "чёрный", доходят до испытуемого, он мучается, перекашивается лицом, но говорит "чёрный".
Сначала я пожал плечами. Хотел уже написать в форум. Потом решил, что вечер и я чего-то не соображаю. Долго не мог понять, о каких четырёх тактах речь, если мы говорим об ассемблерном коде, а не том, что генерит gcc. Даже скопировал этот макрос в файл, чтобы утром разобраться. В не очень хорошем состоянии сейчас, так и утром тоже тупил довольно долго (мучался и перекашивался лицом ;-) ).


Никаких фокусов с sbc и сложными выражениями тут не надо.
Код
.MACRO TAB_Z
    clr    ZH
    subi    ZL, low( -@0 )
    sbci    ZH, high( -@0 )
.ENDMACRO


Цитата(yod @ Mar 11 2009, 10:46) *
Подскажите как коректно переписать это место ассемблерной вставки laughing.gif

Ну теперь, очевидно, так:
Код
uint8_t table[8];

uint8_t rd(uint8_t index)
{
    return table[index];
}


uint8_t rda(uint8_t index)
{
    uint8_t result;
    __asm__ __volatile__ (
        "clr    %B[ptr]"        "\n\t"    
        "subi    %A[ptr], lo8(-%[tbl])"    "\n\t"    
        "subi    %B[ptr], hi8(-%[tbl])"    "\n\t"    
        "ld    %[result], %a[ptr]"
        : [result]"=r"(result)
        : [ptr]"e"(index), [tbl]"m"(table[0])
    );
    return result;
}


Код
rd:
    ldi r30,lo8(table)
    ldi r31,hi8(table)
    add r30,r24
    adc r31,__zero_reg__
    ld r24,Z
    clr r25
    ret


rda:
    mov r30,r24
/* #APP */
    clr    r31
    subi    r30, lo8(-table)
    subi    r31, hi8(-table)
    ld    r24, Z
/* #NOAPP */
    clr r25
    ret


upd: Тю, gcc генерит то, что надо, а ассемблер потом ругается.

upd2: Ещё одни скобки нужны, без них он путается в том, от какого нуля нужно онять tbl для получения -tbl
Цитата
"subi %A[ptr], lo8(-(%[tbl]))" "\n\t"
"subi %B[ptr], hi8(-(%[tbl]))" "\n\t"

Так линкуется и дизассемблер покзывает что надо.

(опять туплю - пока не полез в свой же рабочий асмовый исходник - не вспомнил... как бы это выспаться...)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 14 2009, 11:12
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(ReAl @ Mar 14 2009, 14:02) *
как бы это выспаться...

bb-offtopic.gif
Просто. Забить на всё и выспаться. smile.gif
Я вот закончил первую часть проекта и отоспался... (Формально занимаюсь второй частью) smile.gif
Даже 2 раза за неделю на рыбалку съездил... Лафа!!!
Go to the top of the page
 
+Quote Post
galjoen
сообщение Mar 14 2009, 16:27
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(ReAl @ Mar 14 2009, 13:02) *
Никаких фокусов с sbc и сложными выражениями тут не надо.
Код
.MACRO TAB_Z
    clr    ZH
    subi    ZL, low( -@0 )
    sbci    ZH, high( -@0 )
.ENDMACRO

Согласен. Сам долго не мог вспомнить почему я так написал (с sbc ZH,ZH). Тоже полез в исходники. И вот что там нашёл:
Код
.MACRO TAB2_Z
    subi    ZL,low(-low(@0)); получение
    sbc    ZH,ZH        ; адреса
    sub    ZL,@1           ; в
    sbci    ZH,low(-high((@0)-1))-1; таблице
.ENDMACRO

Вот он прародитель. Для двумерного массива он сделан был. Потом я его скопировал, лишний sub убрал и sbci на subi изменил. И получился у меня вариант для одномерного массива.
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 20:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01571 секунд с 7
ELECTRONIX ©2004-2016