我正在使用STM32F4并尝试从内部调用编写ASM函数 C.该函数在C函数内部调用,也在中断中。 我正在推动并弹出r4-r7。我还需要做其他事吗? 我的假设是r0-r3不需要推动。我也在修改全球 具有ASM功能的变量。我的猜测是这些应该被声明为volatile。 任何提示都会受到欢迎。 另外我注意到ARM概述的Cortex M4指令集与之不同 GCC编译器似乎可以使用的指令。 例如,没有回写,即后增量的r0,[r1],#4是非法的。 是否允许列出哪些ASM指令? 我假设STM32F4使用thumb2
到目前为止它似乎没有起作用,我想知道可能出现的问题是什么 除了装配中的错误
答案 0 :(得分:2)
@ void get_sine(void)
.align 2 @ Align to word boundary
.global get_sine @ This makes it a real symbol
.thumb_func
.type get_sine STT_FUNC @ Declare get_sine to be a function.
get_sine: @ Start of function definition
push {r4-r7}
ldr r0,=pitch @ get pitch address
ldr r1,=expoLUT @ expo_tab address
ldr r7,[r0,#0] @ pitch val into r7
lsl r7,r7,#2
ldr r7,[r1,r7] @ move lookup expo tab value with r7 into r7
ldr r2,=sineLUT @ sine_tab base addy
ldr r4,=WaveBuffer @ storage array addy
ldr r5,=writePos @ get writepos addr
mov r6,#0 @ clear increment r6
outloop:
ldr r3,=phase @ phase address to r3
ldr r1,[r3,#0] @ get current phase
add r1,r1,r7 @ add current phase and ph_inc
str r1,[r3,#0] @ store phase
lsr r0,r1,#18 @ shift it right by 18 into r0 for sine_tab lookup
lsl r0,r0,#2 @ align it
ldr r0,[r2,r0] @ lookup sine val with r0 into r1
lsl r1,r0,#16 @ shift to left channel
add r0,r0,r1 @ add right channel
ldr r1,[r5,#0] @ get writePos
push {r1} @ push it before align
lsl r1,r1,#2 @ align address 4
str r0,[r4,r1] @ store sine to WaveBuffer
pop {r1} @ pop writepos back
add r1,r1,#1 @ increment array pointer writepos
ldr r3,=1024 @ load BUFFERSIZE compare
cmp r1,r3 @ skip if less than BUFFERSIZE
bne skip
mov r1,#0 @ clr writepos if >=BUFFERSIZE
skip:
str r1,[r5,#0] @ store writepos value
add r6,r6,#1 @ increment loop counter
ldr r0,=dataSize @ get datasize counter addr
ldr r1,[r0,#0] @ get val
add r1,r1,#1 @ increment datasize counter
str r1,[r0,#0] @ store counter
cmp r6,#16 @ compare with 16 (i=0;i<16;i++)
bne outloop
pop {r4-r7}
bx lr
.section .rodata
sineLUT:
@ Array goes in here. Type can be .byte, .hword or .word
@ NOTE! No comma at the end of a line! This is important
.word 0x0000,0x000c,0x0018,0x0024,0x0030,0x003c,0x0048,0x0054
.word 0x0064,0x0070,0x007c,0x0088,0x0094,0x00a0,0x00ac,0x00bc
.word 0x00c8,0x00d4,0x00e0,0x00ec,0x00f8,0x0104,0x0114,0x0120
.word 0x012c,0x0138,0x0144,0x0150,0x015c,0x016c,0x0178,0x0184
.word 0x0190,0x019c,0x01a8,0x01b4,0x01c4,0x01d0,0x01dc,0x01e8
.word 0x01f4,0x0200,0x020c,0x021c,0x0228,0x0234,0x0240,0x024c
.word
答案 1 :(得分:1)
您的问题的一些答案在“ARM体系结构的过程调用标准”一书中。这是link。
本书说,前四个寄存器r0-r3(和FPU的s0-15)用于将参数值传递给子程序并从函数返回结果值。它们也可用于在例程中保存中间值(但通常仅用于子例程调用之间)。寄存器r4-r8,r10和r11(以及FPU的s16-s31)用于保存例程的局部变量的值。子程序必须保留该寄存器的内容。
现在关于volatile
。我想是的,你必须使用它来防止可以“制动”你的程序逻辑的编译器优化。
关于你的正弦。英语不是我的自然语言,所以我不太了解你需要什么,但如果你需要一些快速而精确的正弦近似作为问题的一部分,你可能会对这篇文章感兴趣:http://devmaster.net/forums/topic/4648-fast-and-accurate-sinecosine/ http:// www.coranac.com/2009/07/sines /.
最后一个。我几乎完成了Cortex-M4的正弦近似功能。它使用FPU,大约需要30个周期,并在单个浮点范围内带来零错误结果。