Цитата(KARLSON @ Oct 27 2010, 13:24)

Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?
Для вашего же блага, чтоб вы не пробовали записать в эти переменные обычным синтаксисом, а работали с флешью как полагается в данном МК.
Цитата(jorikdima @ Oct 27 2010, 16:46)

К ИАР для МСП у меня тоже есть ряд вопросов. Вечером напишу в эту же тему, если автор не против.
Ну автор, видимо, не против.

Итак, есть один cpp модуль и h файл к нему:
main.cppКод
#include "io430.h"
#include "b.h"
A a;
B bb;
A::A()
{
b = &bb;
}
void main()
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
a.b->f();
a.b->f();
a.b->f();
}
b.hКод
#include "io430.h"
class B
{
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef struct
{
UINT8 UCCTL1;
UINT8 UCCTL0;
UINT16 UCRES[2];
UINT16 UCBR;
UINT8 UCMCTL;
UINT8 UCRES1;
UINT8 UCSTAT;
UINT8 UCRES2;
UINT8 UCRXBUF;
UINT8 UCRES3;
UINT8 UCTXBUF;
UINT8 UCRES4;
UINT8 UCABCTL;
UINT8 UCRES5;
UINT16 UCIRCTL;
UINT16 UCRES6[4];
UINT8 UCIE;
UINT8 UCIFG;
UINT8 UCIV;
} REG_STRUCT;
volatile REG_STRUCT* registers;
public:
_Pragma("inline=forced")
void f() {
volatile REG_STRUCT* const regs = registers;
while (!(regs->UCIFG & UCTXIFG)); // wait while not ready / for RX
regs->UCTXBUF = 0xFF; // write
while (!(regs->UCIFG & UCRXIFG)); // wait for RX buffer (full)
volatile UINT8 dummy = regs->UCRXBUF;
}
};
class A
{
public:
B* b;
A();
};
extern A a;
extern B bb;
Просьба не обращать внимание на цель кода, код выдернут из рабочего проекта, возможно для демонстрации моего вопроса можно было бы и еще укоротить код. Изначально это был класс-обертка для UART, но не суть.
Есть класс B который имеет
важно инлайновый метод f(), есть класс A, который имеет в себе поле-указатель на объект типа B.
В main() я трижды подряд вызываю функцию f(), которую компайлер по моей просьбе инлайнит.
Листинг выглядит так:
Код
volatile REG_STRUCT* const regs = registers;
005C38 421F 1C00 mov.w &a,R15 ЭТО ПОНЯТНО
005C3C 4F2F mov.w @R15,R15
while (!(regs->UCIFG & UCTXIFG)); // wait while not ready / for RX
005C3E B3EF 001D bit.b #0x2,0x1D(R15)
005C42 2BFD jnc 0x5C3E
regs->UCTXBUF = 0xFF; // write
005C44 43FF 000E mov.b #0xFF,0xE(R15)
while (!(regs->UCIFG & UCRXIFG)); // wait for RX buffer (full)
005C48 B3DF 001D bit.b #0x1,0x1D(R15)
005C4C 2BFD jnc 0x5C48
volatile UINT8 dummy = regs->UCRXBUF;
005C4E 4FD1 000C 0000 mov.b 0xC(R15),0x0(SP)
volatile REG_STRUCT* const regs = registers;
005C54 421F 1C00 mov.w &a,R15 НО ЗАЧЕМ ОПЯТЬ?
005C58 4F2F mov.w @R15,R15
while (!(regs->UCIFG & UCTXIFG)); // wait while not ready / for RX
005C5A B3EF 001D bit.b #0x2,0x1D(R15)
005C5E 2BFD jnc 0x5C5A
regs->UCTXBUF = 0xFF; // write
005C60 43FF 000E mov.b #0xFF,0xE(R15)
while (!(regs->UCIFG & UCRXIFG)); // wait for RX buffer (full)
005C64 B3DF 001D bit.b #0x1,0x1D(R15)
005C68 2BFD jnc 0x5C64
volatile UINT8 dummy = regs->UCRXBUF;
005C6A 4FD1 000C 0000 mov.b 0xC(R15),0x0(SP)
volatile REG_STRUCT* const regs = registers;
005C70 421F 1C00 mov.w &a,R15
005C74 4F2F mov.w @R15,R15
В начале он определяет адрес начала структуры registers и кладет ее в R15. Затем этим адресом активно пользуется. Но зачем он при каждом вызове f() делает это??? Ведь
встраивая функцию компайлер прекрасно видит, что с этим регистром ничего не происходит между вызовами ф-ций.
Второй вопрос. Модифицируем f() так:
Код
_Pragma("inline=forced")
void f() {
//volatile REG_STRUCT* const regs = registers;
while (!(registers->UCIFG & UCTXIFG)); // wait while not ready / for RX
registers->UCTXBUF = 0xFF; // write
while (!(registers->UCIFG & UCRXIFG)); // wait for RX buffer (full)
volatile UINT8 dummy = registers->UCRXBUF;
}
Листинг такой () кусок только f():
Код
a.b->f();
005C38 421F 1C00 mov.w &a,R15
void f() {
005C3C 4F2E mov.w @R15,R14
while (!(registers->UCIFG & UCTXIFG)); // wait while not ready / for RX
005C3E B3EE 001D bit.b #0x2,0x1D(R14)
005C42 2BFD jnc 0x5C3E
registers->UCTXBUF = 0xFF; // write
005C44 43FE 000E mov.b #0xFF,0xE(R14)
005C48 4F2F mov.w @R15,R15 ЗАЧЕМ?
while (!(registers->UCIFG & UCRXIFG)); // wait for RX buffer (full)
005C4A B3DF 001D bit.b #0x1,0x1D(R15)
005C4E 2BFD jnc 0x5C4A
volatile UINT8 dummy = registers->UCRXBUF;
005C50 4FD1 000C 0000 mov.b 0xC(R15),0x0(SP)
Зачем он при проверке флага на прием опять пытается определить начало структуры registers? Ведь в R14 этот адрес уже есть, почему он требует константного указателя? Ведь код линеен и сам указатель registers не объявлен как
Код
volatile REG_STRUCT* volatile registers;
Что ему с R14 не живется дальше?
Естественно оптимизация полная по скорости.
Спасибо.