We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I have a "test_fun1()" function call to a inline ASM "test_fun2()". I found that the caller, "test_fun1()" did not keep the R3 before jump to "test_fun2()", which cause the result of the "test_fun1()" is not correct (inline ASM "test_fun2()" use R3).
The same code works fine with Keil MDK-ARM. It also works when I change the Core from M3 to M0.
Does the "test_fun2()" have any problem/violation?
I will be appreciated if anyone can give some suggestions. Thanks.
Following are some information and the code (It has some differences from the original application code, I create a simple ASM version to reproduces the issue).
Sincerely,
Weiting
Caller_R3_source_code.zip
GNU Arm Version: 9 2020-q2-update (gcc-arm-none-eabi-9-2020-q2-update-win32.exe)
ARM_CORE = cortex-m0ARCH_OPTION = -mcpu=$(ARM_CORE) -mthumb -mthumb-interworkC_OPTION = -gdwarf-2 -MD -Wall -Os -mapcs-frame -ffunction-sections -fdata-sectionsL_OPTION = -Wl,-Map=$(TARGET_NAME).map -Wl,--gc-sections --specs=nano.specs
main.c
int result; int main(void) { extern int test_fun1(int a, int b, int c, int d); extern int gTest; result = test_fun1(1, 2, 3, 4); if (gTest != 4) { while (1); // R3 Error here } while (1) // OK { } }
test.c
void test_fun2(int a, int b, int c); int gTest = 0; int test_fun1(int a, int b, int c, int d) { int uStart; uStart = gTest; if (a > 0) { test_fun2(uStart, uStart + c, 5); } uStart += d; gTest = uStart; return 1; } #if defined (__CC_ARM) __asm void test_fun2(int a, int b, int c) { PUSH {R4-R6, LR} MOV R4, R0 LDR R3, =0x1234 ADD R1, R1, R3 POP {R4-R6, PC} } #endif #if defined (__GNUC__) void test_fun2(int a, int b, int c) { __asm volatile("PUSH {R4-R6, LR}"); __asm volatile("MOV R4, R0"); __asm volatile("LDR R3, =0x1234"); __asm volatile("ADD R1, R1, R3"); __asm volatile("POP {R4-R6, PC}"); } #endif
disasm.txt
$t main 0x00000198: b508 .. PUSH {r3,lr} 0x0000019a: 2203 ." MOVS r2,#3 0x0000019c: 2304 .# MOVS r3,#4 0x0000019e: 2102 .! MOVS r1,#2 0x000001a0: 2001 . MOVS r0,#1 0x000001a2: f000f815 .... BL test_fun1 ; 0x1d0 0x000001a6: 4b04 .K LDR r3,[pc,#16] ; [0x1b8] = 0x20000020 0x000001a8: 6018 .` STR r0,[r3,#0] 0x000001aa: 4b04 .K LDR r3,[pc,#16] ; [0x1bc] = 0x2000001c 0x000001ac: 681b .h LDR r3,[r3,#0] 0x000001ae: 2b04 .+ CMP r3,#4 0x000001b0: d000 .. BEQ 0x1b4 ; main + 28 0x000001b2: e7fe .. B 0x1b2 ; main + 26 0x000001b4: e7fe .. B 0x1b4 ; main + 28 0x000001b6: bf00 .. NOP $d 0x000001b8: 20000020 .. DCD 536870944 0x000001bc: 2000001c ... DCD 536870940 $t test_fun2 0x000001c0: b570 p. PUSH {r4-r6,lr} 0x000001c2: 4604 .F MOV r4,r0 0x000001c4: f2412334 A.4# MOV r3,#0x1234 0x000001c8: 4419 .D ADD r1,r1,r3 0x000001ca: bd70 p. POP {r4-r6,pc} 0x000001cc: 4770 pG BX lr 0x000001ce: 0000 .. MOVS r0,r0 $t test_fun1 0x000001d0: b538 8. PUSH {r3-r5,lr} 0x000001d2: 4d07 .M LDR r5,[pc,#28] ; [0x1f0] = 0x2000001c 0x000001d4: 2800 .( CMP r0,#0 0x000001d6: 4611 .F MOV r1,r2 0x000001d8: 682c ,h LDR r4,[r5,#0] 0x000001da: dd04 .. BLE 0x1e6 ; test_fun1 + 22 0x000001dc: 2205 ." MOVS r2,#5 0x000001de: 4620 F MOV r0,r4 0x000001e0: 4421 !D ADD r1,r1,r4 0x000001e2: f7ffffed .... BL test_fun2 ; 0x1c0 0x000001e6: 441c .D ADD r4,r4,r3 0x000001e8: 2001 . MOVS r0,#1 0x000001ea: 602c ,` STR r4,[r5,#0] 0x000001ec: bd38 8. POP {r3-r5,pc} 0x000001ee: bf00 .. NOP $d 0x000001f0: 2000001c ... DCD 536870940