|
Не удается повторить сишный код в асме АРМ., контроллер at91sam7s |
|
|
|
Nov 23 2009, 10:30
|
Местный
  
Группа: Участник
Сообщений: 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); }
|
|
|
|
|
Nov 23 2009, 10:41
|
Гуру
     
Группа: Свой
Сообщений: 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-программе локальные переменные?
|
|
|
|
|
Nov 23 2009, 11:06
|
Местный
  
Группа: Участник
Сообщений: 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, используемы в обработчике прерывания, глобальные, так как они используются еще и в другой функции
|
|
|
|
|
Nov 23 2009, 11:16
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Bulat @ Nov 23 2009, 17:06)  переменный datA,ii,front, используемы в обработчике прерывания, глобальные, так как они используются еще и в другой функции Ну и кто их будет в раме-то менять когда функция на асме? В случае плохого владения асмом всё делается так: ставится максимальная (spd/size) оптимизация и полученный листинг тупо копируется на уровне асм-команд  После этого ничего уже от оптимизации не зависит. В некоторых случаях удаётся ещё оптимизировать листинг, но надо хорошо владеть асмом.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 23 2009, 11:51
|
Местный
  
Группа: Участник
Сообщений: 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]
|
|
|
|
|
Nov 23 2009, 12:19
|

кекс
     
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Nov 23 2009, 12:46
|
Гуру
     
Группа: Свой
Сообщений: 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 Так что попробуйте сначала освоить инструмент.
|
|
|
|
|
Nov 23 2009, 12:49
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(sergeeff @ Nov 23 2009, 18:10)  У вас в С-ой программе сплошь глобальные переменные, а в ASM варианте вы с ними работаете, как с локальными (т.е. вы как-то манипулируете значениями в регистрах, но не значениями в памяти). Конечно все получается короче, но неправильно.
Совет: плюньте вы на ассемблер, ничего вы с бухты-барахты там не наоптимизируете, по сравнению с С/С++ компилятором. тогда у меня вопрос, из-за которого я и взялся за оптимизацию. но его я задам в следующей теме, так как тут уже слишком много ответов.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|