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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Не удается повторить сишный код в асме АРМ., контроллер at91sam7s
Bulat
сообщение Nov 23 2009, 06:15
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



мне необходимо реализовать на асм-е следующий сишный код:
Код
if(datA&0x80000000) regA = 0x20000;
else regA = 0x0;

Но операнд в ARM-команде может иметь макс длину 12 бит, поэтому в асм-е я поступаю следующим образом:
Код
;r1 = datA, regA = r6
  mov      r6, r1
  mov      r6, r6, lsr #28
  and       r6, r6, #0x8                                                    
  ldrne     r6, =0x20000                                                    ;if(datA&0x80000000) regA = 0x20000
  ldreq     r6, =0                                                              ;else regA = 0x0

это правильно?
Заранее благодарен.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 06:34
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



мне необходимо реализовать на асм-е следующий сишный код - обработчик прерывания таймера:
Код
__ramfunc void timer0_irq_handler()
{  
  ii--;                                                                          
  if(ii==0) {MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;}
  MipsTimerBase->TC_RA = 30; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = 60;
  
  if(datA&0x80000000) regA = 0x20000;
  else regA = 0x0;
  regs->PIOA_ODSR = regA|front;    
  datA = datA<<1;  
    
  dummy = MipsTimerBase->TC_SR;  
}

Этот код рабочий, благодаря ему я получаю необходимую последовательность импульсов на выходе.
Так я повторил этот код на асме АРМ:
При прирывании вызываетя следующая функция:
__ramfunc void ASM_timer0_irq()
{
timer0_irq_ASM(ii,datA,front);
}
которая в свою очередь вызывает асм-функциюи сообщает туда 3 параметра.

Код
IO_base         DEFINE  0xFFFFF400
ODSR            DEFINE  0x38
TC_base         DEFINE  0xFFFA0000
TC0_CCR       DEFINE  0x0
TC0_RA          DEFINE  0x14
TC0_RB          DEFINE  0x18
TC0_RC          DEFINE  0x1C
TC0_SR          DEFINE  0x20
TC_CLKDIS     DEFINE  0x2          

PUBLIC     timer0_irq_ASM
                                                            
timer0_irq_ASM                                                                 ;r0 = ii, r1 = dataA, r2 = front

  ldr     r12,=TC_base                                                         ;смещение для TC
  ldr     r11,=IO_base                                                         ;смещение для PIO
  sub     r0, r0, #1                                                              ;ii--
  beq     Stop_TC0
  bne     Work_TC0

Stop_TC0:
  ldr      r7, =TC_CLKDIS
  str      r7,[r12,#TC0_CCR]                                                   ;MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS
  b        timer0_irq_ASM_end  
  
  Work_TC0:
  ldr      r7, =30
  str      r7,[r12, #TC0_RA]                                                    ;MipsTimerBase->TC_RA = 30
  ldr      r7, =60
  str      r7, [r12, #TC0_RB]                                                    ;MipsTimerBase->TC_RB = 60
  str      r7, [r12, #TC0_RC]                                                    ;MipsTimerBase->TC_RC = 60
  
  
  mov      r6, r1, lsr #28                                                       ;смещаем содержимое r1 (datA) вправо на 28 бит, так как операнд не может быть больше 12 бит в длину, а мне необходимо анализировать состояние 32-бита r1
  and      r6, r6, #0x8                                                    
  ldrne    r6, =0x20000                                                        ;if(datA&0x80000000) regA = 0x20000
  ldreq    r6, =0                                                                  ;else regA = 0x0
  orr      r6, r6, r2
  str      r6, [r11, #ODSR]                                                      ;regs->PIOA_ODSR = regA|front
  mov      r0, r0, lsl #1                                                          ;datA = datA<<1
  ldr      r6, [r12, #TC0_SR]                                                    ;dummy = MipsTimerBase->TC_SR
    

  timer0_irq_ASM_end:
  bx       lr

асм-код не работает так же, как и сишный. то есть таймер запускается, импульсы нужной частоты идут, но таймер не останавливается при обнулении счетчика ii и не меняет ldrne r6, =0x20000 или ldreq r6, =0 в зависимости от содержимого r1.

Заранее благодарен.

Сообщение отредактировал Bulat - Nov 23 2009, 07:05
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 23 2009, 06:50
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Bulat @ Nov 23 2009, 09:34) *
это правильно?

Нет, правильно будет так:
Код
;r1 = datA, regA = r6
ANDS     r6,r1,#0x80000000
MOVNE    r6,#0x20000

Числа вида "константа со сдвигом" можно загружать командой MOV. Ну а вообще в таких конструкциях бесполезно пытаться переплюнуть C-компилятор.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Nov 23 2009, 07:02
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Код
tst         r1, #2, 2; -2147483648 (0x80000000)
movne       r6, #2, 16
moveq       r6, #0
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 23 2009, 07:30
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Bulat @ Nov 23 2009, 09:34) *
асм-код не работает так же, как и сишный

Для начала стоит ознакомится с тем кодом, который был сгенерирован компилятором - на 100% уверен, что он компактнее и быстрее приведенного ассемблерного фрагмента (пожалуй, даже при выключенной оптимизации).
Кроме того, если уж хотите использовать ассемблер, стоит почитать стандарт AAPCS - ваш код может быть неработоспособен хотя бы потому, что с регистрами R4-R11 так обращаться нельзя.

Да, ну и логика работы C и asm программ у вас отличаются - первая не вываливается по условию "if(ii==0)".
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Nov 23 2009, 08:06
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Авторы многих книг предупреждают о вреде преждевременной оптимизации. На практике это означает, что сначала надо написать работоспособную программу, а потом заниматься поиском узких мест в ней (если такие будут иметь место) и их оптимизацией.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 23 2009, 08:52
Сообщение #7


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(sergeeff @ Nov 23 2009, 14:06) *
Авторы многих книг предупреждают о вреде преждевременной оптимизации.

smile.gif Можно с этого места поподробней. Прямо как преждевременные роды smile.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Nov 23 2009, 08:58
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(GetSmart @ Nov 23 2009, 12:52) *
smile.gif Можно с этого места поподробней. Прямо как преждевременные роды smile.gif

google://"premature optimization is root of all evil"
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Nov 23 2009, 09:08
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(GetSmart @ Nov 23 2009, 11:52) *
smile.gif Можно с этого места поподробней. Прямо как преждевременные роды smile.gif


Применительно к данному топику: что за нужда писать обработчик прерывания на ассемблере? Не хватает скорости обработки? С/С++ компиляторы генерят не слишком эффективный код? Автор все написал супер эффективно и без ошибок?

Как говорят театральные работники - не верю!
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 09:13
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Nov 23 2009, 13:30) *
Да, ну и логика работы C и asm программ у вас отличаются - первая не вываливается по условию "if(ii==0)".

Почему не выходит по условию ii==0?
Код
  sub     r0, r0, #1     ;ii--
  beq     Stop_TC0     ;r0 == 0
  bne     Work_TC0    ;r0 !=0

где тут ошибка?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 23 2009, 09:27
Сообщение #11


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Bulat @ Nov 23 2009, 15:13) *
Почему не выходит по условию ii==0?
Код
  sub     r0, r0, #1    ;ii--
где тут ошибка?

sub не устанавливает флаги. Нужно SUBS


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Nov 23 2009, 09:35
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Быстрее и короче:

Код
  ldr     r12,=TC_base                                                    ;смещение для TC
  ldr     r11,=IO_base                                                    ;смещение для PIO
  subs     r0, r0, #1                                                            ;ii--
  bne     Work_TC0

Stop_TC0:
  ldr      r7, =TC_CLKDIS
  str      r7,[r12,#TC0_CCR]                                    ;MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS
  bx      lr
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 09:44
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(GetSmart @ Nov 23 2009, 15:27) *
sub не устанавливает флаги. Нужно SUBS


вроде все исправил. но картинка на осциллографе без изменений. таймер запускается с нужной частотой, но не останавливается когда нужно и данные не передаются:
Код
IO_base         DEFINE  0xFFFFF400
ODSR            DEFINE  0x38
TC_base         DEFINE  0xFFFA0000
TC0_CCR       DEFINE  0x0
TC0_RA          DEFINE  0x14
TC0_RB          DEFINE  0x18
TC0_RC          DEFINE  0x1C
TC0_SR          DEFINE  0x20
TC_CLKDIS     DEFINE  0x2  

  PUBLIC     timer0_irq_ASM
                                                            
timer0_irq_ASM                                                                 ;r0 = ii, r1 = dataA, r2 = front

  ldr     r12,=TC_base                                                         ;смещение, для обращения к регистрам TC
  subs    r0, r0, #1                                                             ;ii--
  bne     Work_TC0
  beq     Stop_TC0
  
  
Stop_TC0:
  ldr      r3, =TC_CLKDIS
  str      r3,[r12,#TC0_CCR]                                                   ;MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS
  b        timer0_irq_ASM_end    

  
Work_TC0:
  ldr      r3, =30
  str      r3,[r12, #TC0_RA]                                                    ;MipsTimerBase->TC_RA = 30
  ldr      r3, =60
  str      r3, [r12, #TC0_RB]                                                    ;MipsTimerBase->TC_RB = 60
  str      r3, [r12, #TC0_RC]                                                    ;MipsTimerBase->TC_RC = 60  
  
  ands     r3, r1, #0x80000000                                                    
  movne    r3, #0x20000                                                        ;if(datA&0x80000000) regA = 0x20000
  moveq    r3, #0                                                              ;else regA = 0x0
  
  orr      r3, r3, r2
  ldr      r12,=IO_base
  str      r3, [r12, #ODSR]                                                      ;regs->PIOA_ODSR = regA|front
  mov      r0, r0, lsl #1                                                         ;datA = datA<<1
  ldr      r12,=TC_base
  ldr      r3, [r12, #TC0_SR]                                                    ;dummy = MipsTimerBase->TC_SR

  timer0_irq_ASM_end:
  bx       lr
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 23 2009, 10:02
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Bulat, вы с дизассемблированным кодом C-программы ознакомились? От этого надо начинать.
Более того, могу с уверенностью сказать, что руками оптимизировать там нечего.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 10:18
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Nov 23 2009, 16:02) *
Bulat, вы с дизассемблированным кодом C-программы ознакомились? От этого надо начинать.
Более того, могу с уверенностью сказать, что руками оптимизировать там нечего.

В дизассемблированном коде программы на одну операцию сдвига datA = datA<<1 приходится 5 асм-команд, в то время, как у меня в асм-коде на это тратится одна команда mov r0, r0, lsl #1.
А можно в Си-коде, допустим, в качестве сдвиговой переменной datA назначить один из регистров r0,r1,... и напрямую к нему обращаться из сишного когда?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 23 2009, 10:23
Сообщение #16


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Нельзя же так быстро цитировать biggrin.gif

Bulat, в асм-функции ii меняется только в регистре. Глобальная переменная ii не меняется!

Сообщение отредактировал GetSmart - Nov 23 2009, 10:32


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 10:30
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(GetSmart @ Nov 23 2009, 16:23) *
А вот это что за ерунда? R2 это что?

r2 - это регистр, через который передается значение третьего аргумента функции timer0_irq_ASM, вызываемой из Си-кода при приходе прирывания:
__ramfunc void ASM_timer0_irq()
{
timer0_irq_ASM(ii,datA,front);
}
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 23 2009, 10:41
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Bulat @ Nov 23 2009, 13:18) *
В дизассемблированном коде программы на одну операцию сдвига datA = datA<<1 приходится 5 асм-команд, в то время, как у меня в асм-коде на это тратится одна команда mov r0, r0, lsl #1.

Не верю. Листинг приложите.

Цитата(Bulat @ Nov 23 2009, 13:18) *
А можно в Си-коде, допустим, в качестве сдвиговой переменной datA назначить один из регистров r0,r1,... и напрямую к нему обращаться из сишного когда?

Да компилятор сам все замечательно сделает, если только вы ему мешать не будете. Где, например, в вашей C-программе локальные переменные?
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 11:06
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Nov 23 2009, 16:41) *
Не верю. Листинг приложите.


Да компилятор сам все замечательно сделает, если только вы ему мешать не будете. Где, например, в вашей C-программе локальные переменные?

Дизассемблерный код для функции:
Код
void timer0_irq_handler()
{  
  ii--;                                                                              
  if(ii==0) {MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;}  
  MipsTimerBase->TC_RA = 30; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = 60;

  if(datA&0x80000000) regA = 0x20000;
  else regA = 0x0;        
  regs->PIOA_ODSR = regA|front;    
  datA = datA<<1;  
    
  dummy = MipsTimerBase->TC_SR;
  
}


Код
timer0_irq_handler:
  0000083C  E59F041C  LDR          R0, [PC, #+1052]        ; [0xC60] =ii (0x2001B0)
  00000840  E59F1418  LDR          R1, [PC, #+1048]        ; [0xC60] =ii (0x2001B0)
  00000844  E5911000  LDR          R1, [R1, #+0]
  00000848  E2511001  SUBS         R1, R1, #0x1
  0000084C  E5801000  STR          R1, [R0, #+0]
  if(ii==0) {MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;}
  00000850  E59F0408  LDR          R0, [PC, #+1032]        ; [0xC60] =ii (0x2001B0)
  00000854  E5900000  LDR          R0, [R0, #+0]
  00000858  E3500000  CMP          R0, #0x0
  0000085C  1A000003  BNE          0x000870
  if(ii==0) {MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;}
  00000860  E59F03FC  LDR          R0, [PC, #+1020]        ; [0xC64] =MipsTimerBase (0x17B4)
  00000864  E5900000  LDR          R0, [R0, #+0]
  00000868  E3A01002  MOV          R1, #0x2
  0000086C  E5801000  STR          R1, [R0, #+0]
  MipsTimerBase->TC_RA = 30; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = 60;
  00000870  E59F03EC  LDR          R0, [PC, #+1004]        ; [0xC64] =MipsTimerBase (0x17B4)
  00000874  E5900000  LDR          R0, [R0, #+0]
  00000878  E3A0101E  MOV          R1, #0x1E
  0000087C  E5801014  STR          R1, [R0, #+20]
  MipsTimerBase->TC_RA = 30; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = 60;
  00000880  E3A0003C  MOV          R0, #0x3C
  00000884  E59F13D8  LDR          R1, [PC, #+984]         ; [0xC64] =MipsTimerBase (0x17B4)
  00000888  E5911000  LDR          R1, [R1, #+0]
  0000088C  E581001C  STR          R0, [R1, #+28]
  00000890  E59F13CC  LDR          R1, [PC, #+972]         ; [0xC64] =MipsTimerBase (0x17B4)
  00000894  E5911000  LDR          R1, [R1, #+0]
  00000898  E5810018  STR          R0, [R1, #+24]
        if(datA&0x80000000) regA = 0x20000;
  0000089C  E59F03B8  LDR          R0, [PC, #+952]         ; [0xC5C] =datA (0x2001A0)
  000008A0  E5900000  LDR          R0, [R0, #+0]
  000008A4  E3100480  TST          R0, #0x80000000
  000008A8  0A000003  BEQ          0x0008BC
        if(datA&0x80000000) regA = 0x20000;
  000008AC  E59F03A0  LDR          R0, [PC, #+928]         ; [0xC54] =regA (0x2001AC)
  000008B0  E3A01B80  MOV          R1, #0x20000            ; 0x208B8
  000008B4  E5801000  STR          R1, [R0, #+0]
  000008B8  EA000002  B            0x0008C8
        else regA = 0x0;
  000008BC  E59F0390  LDR          R0, [PC, #+912]         ; [0xC54] =regA (0x2001AC)
  000008C0  E3A01000  MOV          R1, #0x0                ; 0x8C8
  000008C4  E5801000  STR          R1, [R0, #+0]
    regs->PIOA_ODSR = regA|front;    
  000008C8  E59F0380  LDR          R0, [PC, #+896]         ; [0xC50] =regs (0x200000)
  000008CC  E5900000  LDR          R0, [R0, #+0]
  000008D0  E59F137C  LDR          R1, [PC, #+892]         ; [0xC54] =regA (0x2001AC)
  000008D4  E5911000  LDR          R1, [R1, #+0]
  000008D8  E59F2378  LDR          R2, [PC, #+888]         ; [0xC58] =front (0x200108)
  000008DC  E5922000  LDR          R2, [R2, #+0]
  000008E0  E1921001  ORRS         R1, R2, R1
  000008E4  E5801438  STR          R1, [R0, #+1080]
    datA = datA<<1;  
  000008E8  E59F036C  LDR          R0, [PC, #+876]         ; [0xC5C] =datA (0x2001A0)
  000008EC  E59F1368  LDR          R1, [PC, #+872]         ; [0xC5C] =datA (0x2001A0)
  000008F0  E5911000  LDR          R1, [R1, #+0]
  000008F4  E1B01081  MOVS         R1, R1, LSL #1
  000008F8  E5801000  STR          R1, [R0, #+0]
    dummy = MipsTimerBase->TC_SR;
  000008FC  E59F0120  LDR          R0, [PC, #+288]         ; [0xA24] =dummy (0x2001C8)
  00000900  E59F135C  LDR          R1, [PC, #+860]         ; [0xC64] =MipsTimerBase (0x17B4)
  00000904  E5911000  LDR          R1, [R1, #+0]
  00000908  E5911020  LDR          R1, [R1, #+32]
  0000090C  E5801000  STR          R1, [R0, #+0]
}
  00000910  E12FFF1E  BX           LR


обратите внимание на:
Код
datA = datA<<1;  
  000008E8  E59F036C  LDR          R0, [PC, #+876]         ; [0xC5C] =datA (0x2001A0)
  000008EC  E59F1368  LDR          R1, [PC, #+872]         ; [0xC5C] =datA (0x2001A0)
  000008F0  E5911000  LDR          R1, [R1, #+0]
  000008F4  E1B01081  MOVS         R1, R1, LSL #1
  000008F8  E5801000  STR          R1, [R0, #+0]


переменный datA,ii,front, используемы в обработчике прерывания, глобальные, так как они используются еще и в другой функции
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 23 2009, 11:16
Сообщение #20


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Bulat @ Nov 23 2009, 17:06) *
переменный datA,ii,front, используемы в обработчике прерывания, глобальные, так как они используются еще и в другой функции

Ну и кто их будет в раме-то менять когда функция на асме?

В случае плохого владения асмом всё делается так: ставится максимальная (spd/size) оптимизация и полученный листинг тупо копируется на уровне асм-команд smile.gif После этого ничего уже от оптимизации не зависит. В некоторых случаях удаётся ещё оптимизировать листинг, но надо хорошо владеть асмом.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 11:51
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



я имел в виду лишние обращения к памяти, которых в моем коде нет:
000008E8 E59F036C LDR R0, [PC, #+876] ; [0xC5C] =datA (0x2001A0)
000008EC E59F1368 LDR R1, [PC, #+872] ; [0xC5C] =datA (0x2001A0)
000008F0 E5911000 LDR R1, [R1, #+0]

000008F4 E1B01081 MOVS R1, R1, LSL #1 - собственно само смещение.

000008F8 E5801000 STR R1, [R0, #+0]
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Nov 23 2009, 12:10
Сообщение #22


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



У вас в С-ой программе сплошь глобальные переменные, а в ASM варианте вы с ними работаете, как с локальными (т.е. вы как-то манипулируете значениями в регистрах, но не значениями в памяти). Конечно все получается короче, но неправильно.

Совет: плюньте вы на ассемблер, ничего вы с бухты-барахты там не наоптимизируете, по сравнению с С/С++ компилятором.
Go to the top of the page
 
+Quote Post
defunct
сообщение Nov 23 2009, 12:19
Сообщение #23


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(sergeeff @ Nov 23 2009, 14:10) *
Совет: плюньте вы на ассемблер, ничего вы с бухты-барахты там не наоптимизируете, по сравнению с С/С++ компилятором.

Или ...
Используйте FIQ конкретно для одного только этого прерывания, храните свои переменные в R8, R9, R10.
R11, R12 можете пользовать как рабочие регистры.

R0...R7 по возможности не трогайте, чтобы их не надо было сохранять.


Цитата
Код
  beq     Stop_TC0
  bne     Work_TC0

Stop_TC0:

здесь инструкция beq лишняя, т.к. и без нее выполнение перейдет на Stop_TCO когда рез-тат==0.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 23 2009, 12:46
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Bulat @ Nov 23 2009, 14:06) *
переменный datA,ii,front, используемы в обработчике прерывания, глобальные, так как они используются еще и в другой функции

А RegA и dummy - просто под горячую руку попали?

Цитата(Bulat @ Nov 23 2009, 14:51) *
я имел в виду лишние обращения к памяти, которых в моем коде нет

Ну, оптимизатор явно выключен. Для нормально откомпилированной функции дизассемблер будет выглядеть примерно так:
Код
        0x00000000:    e59fc168    h...    LDR      r12,[pc,#360] ; [.data$0 = 0x170] = 0
        0x00000004:    e59c0004    ....    LDR      r0,[r12,#4]
        0x00000008:    e2501001    ..P.    SUBS     r1,r0,#1
        0x0000000c:    e28c0000    ....    ADD      r0,r12,#0
        0x00000010:    e58c1004    ....    STR      r1,[r12,#4]
        0x00000014:    e5900010    ....    LDR      r0,[r0,#0x10]
        0x00000018:    03a01002    ....    MOVEQ    r1,#2
        0x0000001c:    05801000    ....    STREQ    r1,[r0,#0]
        0x00000020:    e3a0101e    ....    MOV      r1,#0x1e
        0x00000024:    e5801014    ....    STR      r1,[r0,#0x14]
        0x00000028:    e3a0103c    <...    MOV      r1,#0x3c
        0x0000002c:    e580101c    ....    STR      r1,[r0,#0x1c]
        0x00000030:    e5801018    ....    STR      r1,[r0,#0x18]
        0x00000034:    e59c100c    ....    LDR      r1,[r12,#0xc]
        0x00000038:    e59c3008    .0..    LDR      r3,[r12,#8]
        0x0000003c:    e2112102    .!..    ANDS     r2,r1,#0x80000000
        0x00000040:    13a02802    .(..    MOVNE    r2,#0x20000
        0x00000044:    e1822003    . ..    ORR      r2,r2,r3
        0x00000048:    e59c3014    .0..    LDR      r3,[r12,#0x14]
        0x0000004c:    e5832038    8 ..    STR      r2,[r3,#0x38]
        0x00000050:    e1a01081    ....    LSL      r1,r1,#1
        0x00000054:    e58c100c    ....    STR      r1,[r12,#0xc]
        0x00000058:    e5900020     ...    LDR      r0,[r0,#0x20]
        0x0000005c:    e12fff1e    ../.    BX       r14


Так что попробуйте сначала освоить инструмент.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Nov 23 2009, 12:49
Сообщение #25


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(sergeeff @ Nov 23 2009, 18:10) *
У вас в С-ой программе сплошь глобальные переменные, а в ASM варианте вы с ними работаете, как с локальными (т.е. вы как-то манипулируете значениями в регистрах, но не значениями в памяти). Конечно все получается короче, но неправильно.

Совет: плюньте вы на ассемблер, ничего вы с бухты-барахты там не наоптимизируете, по сравнению с С/С++ компилятором.


тогда у меня вопрос, из-за которого я и взялся за оптимизацию. но его я задам в следующей теме, так как тут уже слишком много ответов.
Go to the top of the page
 
+Quote Post

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

 


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


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