Цитата(Maik-vs @ Mar 8 2009, 19:17)

Какое странное и невнятное обсуждение. То есть некоторые обвиняют ассемблер в его "бедности", не понимании структур и т.д. А я вот видел множество обсуждений сишников: то как объявить переменную в нужной памяти, то как проинвертировать бит в порту то ещё что-нибудь, что у ассемблерщика вызовет недоумённую улыбку.
Такой язык. И можно написать кучу макросов каждому на свой вкус, в том числе и для доступа к структурам. К Вашим структурам. А вообще-то конечно, кому что - есть и VBA или вот ЛИСП интересный язык

Ещё раз отмечаю. Само написание проги на асме, как правило занимает даже меньше времени (особенно для млких проектов) чем на асме. Я имею ввиду грамотное написание там и там. Но ... сопровождение и развитие проекта на Си ... на порядок быстрее и комфортнее. На порядок это в 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