Page 1 of 5

IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 12:22
by DimkaM
Как в ИАРе сделать хитрый макрос?
незнаю как объяснить.
допустим есть в проге вот такой вызов:
Code: Select all
if (disk_read(fs->drv, fs->win, sector,1) != RES_OK)
   return FR_DISK_ERR;
Мне его ручками приходится изменять на такое:
Code: Select all
SET_DIO_PAR(fs->drv, fs->win, sector,1);
if (disk_read() != RES_OK)
   return FR_DISK_ERR;
так как в ассемблерной вставке тяжело такую кучу параметров юзать, приходится юзать статичную структуру. SET_DIO_PAR это макрос который заполняет структуру:
Code: Select all
//Parameters for disk_read and disk_write
typedef struct {
   BYTE  drv;
   const BYTE* buf;
   DWORD* sec;
   BYTE  num;
} DIO_PAR;
extern DIO_PAR dio_par;
#define SET_DIO_PAR(dr_drv,dr_buf,dr_sec,dr_num) {\
  dio_par.drv=dr_drv; \
  dio_par.buf=dr_buf; \
  dio_par.sec=&dr_sec; \
  dio_par.num=dr_num;}

И у меня не получается сделать макрос который бы заполнял структуру, вызавал дискодрайвер и возвращал от него результат.
В Сях я непонимаю, ткните носом в мануал по макросам плиз, а то фатфс периодически обновляется и руками неохота патчить.
Изначально была промежуточная функция, но в странице не хватало места под драйвер NeoGS-SD

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 12:24
by DimkaM
deathsoft wrote:Юзать надо естественно структуру на стеке с адресацией через IX, IY. В программу на асме передавать адрес этой структуры.

Про говнокод ужо понял, но чёртова экономика...

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 12:49
by jdigreze
Скинь код фатфс на мыло, гляну как оно у тебя там.

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 14:09
by fk0
Первым показателем дурости является заведение собственных типов данных взаместо точно таких же штатных (man stdint).

Во-вторых макросы лучше писать как do { тело } while(0) -- что исключает глюки от применения макроса где попало.

В-третьих если нужно взять адрес внутри макроса -- заведи в теле {} внутреннюю переменную, ей присвой аргумент макроса, и адрес этой переменной передавай. Только у тебя-то работать ниихуя не будет всё равно (потому, блядь, и в стеке), потому, что в твоём случае время существования dr_sec хуй знает какое. Нахуя вообще ссылки на переменные (с хуй знает каким временем существования) в структуру класть? Проще в стек целиком те нещастные 32 бита затолкать и через LD E, (IX+N): LD D, (IX+N+1) извлекать в вызываемой функции. Или хоть в твою статичную стуктуру, но целиком, не ссылку.

В-четвёртых в таких функциях указатели на хуй знает что принято обзывать типом void, чтоб потом по всем исходникам не ебаться с приведением к твоему самотельному BYTE.

В-пятых весь вызов функции можно замаскировать в один макрос, который и в структуру присвоит и функцию вызовет и результат даже вернёт (последнее, если не GCC, тоже только через статическую переменную).

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 16:02
by TS-Labs
Russian support - senseless and ruthless...

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 19:13
by DimkaM
fk0 wrote:и результат даже вернёт (последнее, если не GCC, тоже только через статическую переменную).
Во, это самое интересное. Вся проблема у меня была с результатом, буду пробовать через статику.

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 19:17
by deathsoft
DimkaM wrote:Во, это самое интересное. Вся проблема у меня была с результатом, буду пробовать через статику

В доке по иару полностью описан оспособ передачи параметров из процедур на Ц в процедуры на ассемблере и возврат значений. Обычно передают указатель на структуру (структура при этом - обычная локальная переменная), никто структуры по значению не передает. Возвращаемое значение обычно int или указатель (структуры по значению тоже никто не возвращает) и Z80 тут не причем, это азы программирования на Ц.

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 19:26
by fk0
Типичный пример возвращаемой по значению структуры -- div_t. На самом деле для маленьких структур оверхеда минимум. А вся статика потоко-небезопасна. Или в качестве таковой используется указатель (на эту статику) передаваемый в функцию. Ещё жутче. Про TLS на z80 лучше даже не задумываться.

Да, "потокобезопасность" к реальной многопоточности никакого отношения не имеет. Достаточно асинхронных сигналов или прерываний.

PS: а в буханках финских студнтов можно в круглые скобки вписывать ещё и фигурные, в ваших поделках недовыпускников гарварда так нельзя:

Code: Select all
#include <stdint.h>
extern struct s_blablabla {
        fast_int8_t alpha;
        uint16_t beta;
        uint32_t gamma;
        long phi;
} stat_args;
   
#define MACRO(arg1, arg2, arg3, arg4) ({ \
        int_fast8_t retval; \
        stat_args.alpga=arg1, stat_args.beta=arg2, stat_args.gamma=arg3, stat_args.phi=arg4; \
        retval=function(); \
        if (retval < 0) retval=ME_OK; \
                else retval=ME_FAIL; \
        retval; \
})

далее:

int result = MACRO(1,2,3,4); ....

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 19:37
by DimkaM
deathsoft wrote:В доке по иару полностью описан оспособ передачи параметров из процедур на Ц в процедуры на ассемблере и возврат значений.
Это всё я умею, изначально так и было, но в целях экономии перешол на статику. Экономия вышла ~1.5кб.

У меня проблема именно с макросом.

Re: IAR Вопрос про макрос

PostPosted: 08 Jan 2012, 19:41
by fk0
С макросом нет проблемы (или в чём она???) Проблема с плохим пониманием как работает язык C...