ARM-GCC has compilation errors for function pointer calls? [The cause has been found]

Publisher:zuiquanLatest update time:2021-09-15 Source: eefocusKeywords:ARM-GCC Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Function pointers are the basis for implementing callback functions, and callback functions are the basis of C program architecture. Therefore, the importance of function pointers is self-evident. However, when testing the program on the ARM development board recently, I found that although the function pointer can be compiled, it always reports an error when running. The following is the source code of the simplest test program.


static void test()

{

    puts("testn");

}


static void(*f)() = test;

void Main(void)

{

    led_init();

    key_init();

    io_init(0);


    f();


    while(1){

        puts("-------hello from main()----------n");

        delay(100000);

    }

}


The assembly code compiled with gcc -S is as follows:


    .cpu arm10tdmi

    .eabi_attribute 20, 1

    .eabi_attribute 21, 1

    .eabi_attribute 23, 3

    .eabi_attribute 24, 1

    .eabi_attribute 25, 1

    .eabi_attribute 26, 2

    .eabi_attribute 30, 6

    .eabi_attribute 34, 0

    .eabi_attribute 18, 4

    .file "main.c"

    .section .rodata

    .align 2

.LC0:

    .ascii "test1200"

    .text

    .align 2

    .syntax unified

    .arm

    .fpu softvfp

    .type test, %function

test:

    @ args = 0, pretend = 0, frame = 0

    @frame_needed = 1, uses_anonymous_args = 0

    push {fp, lr}

    add fp, sp, #4

    ldr r0, .L2

    bl puts

    nop

    pop {fp, pc}

.L3:

    .align 2

.L2:

    .word .LC0

    .size test, .-test

    .data

    .align 2

    .type f, %object

    .size f, 4

f:

    .word test

    .section .rodata

    .align 2

.LC1:

    .ascii "-------hello from main()----------1200"

    .text

    .align 2

.LC1:

    .ascii "-------hello from main()----------1200"

    .text

    .align 2

    .global Main

    .syntax unified

    .arm

    .fpu softvfp

    .type Main, %function

Main:

    @ args = 0, pretend = 0, frame = 0

    @frame_needed = 1, uses_anonymous_args = 0

    push {fp, lr}

    add fp, sp, #4

    bl led_init

    bl key_init

    mov r0, #0

    bl io_init

    ldr r3, .L6

    ldr r3, [r3]

    blx r3

.L5:

    ldr r0, .L6+4

    bl puts

    ldr r0, .L6+8

    bl delay

    b .L5

.L7:

    .align 2

.L6:

    .word f

    .word .LC1

    .word 100000

    .size Main, .-Main

    .ident "GCC: (GNU) 6.2.0"

    .section .note.GNU-stack,"",%progbits


It can be seen that when the function pointer is called, it is compiled into a BLX instruction. This instruction jumps and changes the running state (ARM and THUMB switch). Obviously, this compilation is wrong. Can an expert help analyze what went wrong?


Are special compilation parameters required?


Headache!!!


2016-12-20 Update:


The reasons have been found, the key points are as follows:


GCC compiles absolute address calls (including function pointer calls) into BLX Rn instructions. BX, BLX instructions are used for absolute jumps (B, BL is used for jumps) to the address contained in Rn. In summary, the X has two meanings: (1) It indicates whether to switch between ARM/Thum based on whether the lowest bit of Rn is 0. (2) It can jump to an absolute address.


The instruction set of S3C2440A does not have BLX, but only BX. Therefore, an invalid instruction error will occur during operation.


Solutions:

(1) Run GCC with appropriate options to avoid generating BLX instructions. It is not clear what options are needed.

(2) Use the Undefined exception handler to simulate the BLX instruction. This may seem complicated, but it is actually very simple to implement and has been implemented in v0.9.

Keywords:ARM-GCC Reference address:ARM-GCC has compilation errors for function pointer calls? [The cause has been found]

Previous article:Read data from NAND Flash and move the code to SDRAM for execution
Next article:GNU Freestanding (Naked) C ARM cross-development environment creation and testing

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号