Пишу под STM32 (BluePill).
Есть вот такая функция:
__attribute__((always_inline, section(".ramfunc")))
uint16_t readAddressBus()
{
// Для ускорения адрес вначале считается 32-х битным чтобы проще работать
// с 32-х битным регистром PA, и только в конце он один раз преобразуется в 16 бит
uint32_t addr = 0;
// Установка на мультиплексоре сегмента адреса 00
GPIOB->BSRR = 0 | (GPIO_BSRR_BR3_Msk | GPIO_BSRR_BR4_Msk );
// Считывается и запоминается значение ножек сегмента 0
addr = ((GPIOA->IDR & 0x0F00) >> 8);
// Установка на мультиплексоре сегмента адреса 01
GPIOB->BSRR = 0 | (GPIO_BSRR_BS3_Msk | GPIO_BSRR_BR4_Msk );
// Считывается и запоминается значение ножек сегмента 1
addr = addr | ((GPIOA->IDR & 0x0F00) >> 4);
// Установка на мультиплексоре сегмента адреса 10
GPIOB->BSRR = 0 | (GPIO_BSRR_BR3_Msk | GPIO_BSRR_BS4_Msk );
// Считывается и запоминается значение ножек сегмента 2
addr = addr | (GPIOA->IDR & 0x0F00);
// Установка на мультиплексоре сегмента адреса 11
GPIOB->BSRR = 0 | (GPIO_BSRR_BS3_Msk | GPIO_BSRR_BS4_Msk );
// Считывается и запоминается значение ножек сегмента 3
addr = addr | ((GPIOA->IDR & 0x0F00) << 4);
return (uint16_t) addr;
}
Она вызывается из main loop:
__attribute__((noinline, section(".ramfunc")))
void mainLoop()
{
...
// Нужно получить текущий адрес с ША
uint16_t addr=readAddressBus();
...
}
В дизассемблере ARM это дело представлено таким образом:
Disassembly of section .ramfunc:
080004d0 <readAddressBus>:
80004d0: f44f 13c0 mov.w r3, #1572864 ; 0x180000
80004d4: 490d ldr r1, [pc, #52] ; (800050c <readAddressBus+0x3c>)
80004d6: 4a0e ldr r2, [pc, #56] ; (8000510 <readAddressBus+0x40>)
80004d8: 480e ldr r0, [pc, #56] ; (8000514 <readAddressBus+0x44>)
80004da: 610b str r3, [r1, #16]
80004dc: 6893 ldr r3, [r2, #8]
80004de: 6108 str r0, [r1, #16]
80004e0: 6890 ldr r0, [r2, #8]
80004e2: f3c3 2303 ubfx r3, r3, #8, #4
80004e6: 0900 lsrs r0, r0, #4
80004e8: f000 00f0 and.w r0, r0, #240 ; 0xf0
80004ec: 4318 orrs r0, r3
80004ee: 4b0a ldr r3, [pc, #40] ; (8000518 <readAddressBus+0x48>)
80004f0: 610b str r3, [r1, #16]
80004f2: 6893 ldr r3, [r2, #8]
80004f4: f403 6370 and.w r3, r3, #3840 ; 0xf00
80004f8: 4318 orrs r0, r3
80004fa: 2318 movs r3, #24
80004fc: 610b str r3, [r1, #16]
80004fe: 6893 ldr r3, [r2, #8]
8000500: 011b lsls r3, r3, #4
8000502: f403 4370 and.w r3, r3, #61440 ; 0xf000
8000506: 4318 orrs r0, r3
8000508: 4770 bx lr
800050a: bf00 nop
800050c: 40010c00 andmi r0, r1, r0, lsl #24
8000510: 40010800 andmi r0, r1, r0, lsl #16
8000514: 00100008 andseq r0, r0, r8
8000518: 00080010 andeq r0, r8, r0, lsl r0
0800051c <mainLoop>:
800051c: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
8000520: 2100 movs r1, #0
8000522: f44f 15c0 mov.w r5, #1572864 ; 0x180000
8000526: f04f 0c18 mov.w ip, #24
800052a: f44f 3480 mov.w r4, #65536 ; 0x10000
800052e: f04f 0e01 mov.w lr, #1
8000532: 4a20 ldr r2, [pc, #128] ; (80005b4 <mainLoop+0x98>)
8000534: 4820 ldr r0, [pc, #128] ; (80005b8 <mainLoop+0x9c>)
8000536: 4e21 ldr r6, [pc, #132] ; (80005bc <mainLoop+0xa0>)
8000538: 4f21 ldr r7, [pc, #132] ; (80005c0 <mainLoop+0xa4>)
800053a: f8df 8088 ldr.w r8, [pc, #136] ; 80005c4 <mainLoop+0xa8>
800053e: 6893 ldr r3, [r2, #8]
8000540: f013 0fc0 tst.w r3, #192 ; 0xc0
8000544: d005 beq.n 8000552 <mainLoop+0x36>
8000546: 2900 cmp r1, #0
8000548: d0f9 beq.n 800053e <mainLoop+0x22>
800054a: f8c2 e010 str.w lr, [r2, #16]
800054e: 2100 movs r1, #0
8000550: e7f5 b.n 800053e <mainLoop+0x22>
8000552: 6115 str r5, [r2, #16]
8000554: 6883 ldr r3, [r0, #8]
8000556: 6116 str r6, [r2, #16]
8000558: f3c3 2a03 ubfx sl, r3, #8, #4
800055c: 6883 ldr r3, [r0, #8]
800055e: 6117 str r7, [r2, #16]
8000560: ea4f 1913 mov.w r9, r3, lsr #4
8000564: 6883 ldr r3, [r0, #8]
8000566: f009 09f0 and.w r9, r9, #240 ; 0xf0
800056a: f8c2 c010 str.w ip, [r2, #16]
800056e: f403 6370 and.w r3, r3, #3840 ; 0xf00
8000572: ea49 090a orr.w r9, r9, sl
8000576: ea43 0909 orr.w r9, r3, r9
800057a: 6883 ldr r3, [r0, #8]
800057c: 011b lsls r3, r3, #4
800057e: f403 4370 and.w r3, r3, #61440 ; 0xf000
8000582: ea43 0309 orr.w r3, r3, r9
8000586: f483 4900 eor.w r9, r3, #32768 ; 0x8000
800058a: f1b9 0f04 cmp.w r9, #4
800058e: bf8f iteee hi
8000590: f04f 0988 movhi.w r9, #136 ; 0x88
8000594: 4443 addls r3, r8
8000596: f5a3 4300 subls.w r3, r3, #32768 ; 0x8000
800059a: f893 9000 ldrbls.w r9, [r3]
800059e: 6893 ldr r3, [r2, #8]
80005a0: b29b uxth r3, r3
80005a2: ea43 2309 orr.w r3, r3, r9, lsl #8
80005a6: 60d3 str r3, [r2, #12]
80005a8: 2900 cmp r1, #0
80005aa: d1c8 bne.n 800053e <mainLoop+0x22>
80005ac: 6114 str r4, [r2, #16]
80005ae: 2101 movs r1, #1
80005b0: e7c5 b.n 800053e <mainLoop+0x22>
80005b2: bf00 nop
80005b4: 40010c00 andmi r0, r1, r0, lsl #24
80005b8: 40010800 andmi r0, r1, r0, lsl #16
80005bc: 00100008 andseq r0, r0, r8
80005c0: 00080010 andeq r0, r8, r0, lsl r0
80005c4: 20000000 andcs r0, r0, r0
И я вижу, что код функции readAddressBus() оттранслировался в отдельные адреса. Но я нигде не вижу вызова этой функции. При этом я вижу искаженный код данной функции внутри mainLoop(), значит readAddressBus() вроде как заинлайнилась.
Но тогда зачем сделана реализация этой функции в отдельных адресах, если эта реализация вообще не используется?
Исходник на Си: https://github.com/xintrea/mikroshamem/blob/c00c10606dca71d3531c45f70b1169732...
Ассемблер: https://pastebin.com/gpc4tA03