Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Gcc -使通用寄存器正常运行所需的Os标志_Gcc_Assembly_Arm_Cpu Registers - Fatal编程技术网

Gcc -使通用寄存器正常运行所需的Os标志

Gcc -使通用寄存器正常运行所需的Os标志,gcc,assembly,arm,cpu-registers,Gcc,Assembly,Arm,Cpu Registers,我目前正在使用TI EK-LM4F120XL板。该板包含一个Cortex-M4F cpu。我正在使用以下链: ARM-GCC-None-EABI 和以下调试器: 开放性强迫症 问题是我需要使用-Os标志来防止奇怪的行为。例如,使用TI提供的代码: 默认链接器脚本: MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x

我目前正在使用TI EK-LM4F120XL板。该板包含一个Cortex-M4F cpu。我正在使用以下链:

ARM-GCC-None-EABI

和以下调试器:

开放性强迫症

问题是我需要使用-Os标志来防止奇怪的行为。例如,使用TI提供的代码:

默认链接器脚本:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.isr_vector))
        *(.text*)
        *(.rodata*)
        _etext = .;
    } > FLASH

    .data : AT(ADDR(.text) + SIZEOF(.text))
    {
        _data = .;
        *(vtable)
        *(.data*)
        _edata = .;
    } > SRAM

    .bss :
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
    } > SRAM
}
启动\u gcc.c文件:

还有一个非常简单的闪光灯:

int
main(void)
{
    volatile unsigned long ulLoop;

    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF;

    //
    // Do a dummy read to insert a few cycles after enabling the peripheral.
    //
    ulLoop = SYSCTL_RCGC2_R;

    //
    // Enable the GPIO pin for the LED (PF3).  Set the direction as output, and
    // enable the GPIO pin for digital function.
    //
    GPIO_PORTF_DIR_R = 0x08;
    GPIO_PORTF_DEN_R = 0x08;

    //
    // Loop forever.
    //
    while(1)
    {
        //
        // Turn on the LED.
        //
        GPIO_PORTF_DATA_R |= 0x08;

        //
        // Delay for a bit.
        //
        for(ulLoop = 0; ulLoop < 200000; ulLoop++)
        {
        }

        //
        // Turn off the LED.
        //
        GPIO_PORTF_DATA_R &= ~(0x08);

        //
        // Delay for a bit.
        //
        for(ulLoop = 0; ulLoop < 200000; ulLoop++)
        {
        }
    }
}
如您所见,编译命令包含一个-Os参数。如果我把它添加到命令中,一切正常,但是如果我删除它,寄存器7开始表现得非常奇怪:

(gdb) monitor reg
===== arm v7m registers
(0) r0 (/32): 0x00000000
...
(7) r7 (/32): 0x200000F0
...
(13) sp (/32): 0x200000F0
...
(17) msp (/32): 0x200000F0
...
===== Cortex-M DWT registers
...
(36) dwt_3_function (/32)
(gdb) cont
...
(gdb) monitor reg
===== arm v7m registers
...
(7) r7 (/32): 0x200000E0
...
(13) sp (/32): 0x200000E0
...
(17) msp (/32): 0x200000E0
(18) psp (/32): 0x00000000
...
===== Cortex-M DWT registers
...
(36) dwt_3_function (/32)
可以找到完全转储

R7的值与SP MSP=活动SP相同!为什么会这样

如果我尝试使用以下命令写入R7:

MOV     R7, R0
这个程序只是遇到了一个严重的错误


那么,为什么这个-Os标志如此重要呢?为什么R7在没有它的情况下表现得如此怪异?

GCC在thumb模式下使用R7作为FP。如果没有使用任何优化标志来避免这种行为,请尝试-fomit frame pointer

我不太明白。为什么r7如此重要?我看不到任何显式使用r7的东西。r7是一个通用cpu寄存器,其行为应该是这样的。cpu regs总是被编译代码隐式使用。那么呢?据我所知,这就是这里发生的事情。您发现gcc在使用register做一些事情时遇到了问题,您正在寻找解决方案。。。请首先给我们一个gcc不能存储任何它想要的东西的原因——比如SP帧指针[FP]的副本正如下面的答案所指出的——无论它想在哪里——就像在r7中一样。硬件没有定义ABI——通用定义了它在硬件中的使用,即在指令编码中将它用作源/目标/基址寄存器时没有任何限制。软件可以用它做什么完全取决于编译器和它遵循的任何ABI。还值得考虑防止这种行为的原因,因为它是故意存在的。。。仅仅为了r7正常运行而禁用它不是一个好主意…谢谢!还有一个问题:你如何解释设置R7会导致严重故障?@Cheiron嗯,因为这是最重要的。当你试图从一些现在甚至都不指向RAM的东西(更不用说堆栈)的偏移量处访问局部变量时,你认为这会有多好?@FreddieChopin Afaik的目的只是为了调试或回溯?我不知道OP是如何改变R7的,如果它是内联程序集,他可能应该“破坏”它。虽然这是一个很好的开始,说它是堆栈问题,但我认为fp本身不会引起问题,除非GCC有缺陷。例如,对于完整的下行堆栈,void*voidunsigned longpulStack+sizeofpulStack可以是void*voidunsigned longpulStack+sizeofpulStack-1。-O2和-O3选项通常会使用更多的堆栈空间-操作系统从不内联,总是弹出堆栈帧。
MOV     R7, R0