简体   繁体   English

使用“riscv-none-embed-gcc”时,如何在 main() 函数中将局部变量设置为数据内存地址?

[英]How can i set up local variable in main() function to data memory address when using "riscv-none-embed-gcc"?

enter image description here在此处输入图像描述

This picture show that I hope to do, here have two memory.这张图是我希望做的,这里有两个记忆。

The program memory and data memory, when I want to use data, it'll go data memory get that data.程序存储器和数据存储器,当我要使用数据时,它会去数据存储器获取该数据。

My c code here:我的c代码在这里:

#define XRAM0 0x4000      // REG I/O

int b=0x35;

void main ()
{
    
    int a=0x55;        // i hope GCC compiler can initial 0x55 value into mem_data region
    
    int *address;
    
    address = XRAM0;
    address[0]=a;      // But GCC compiler always read a variable from Dbus(not initialed yet, there is no value 0x55)
    address[1]=b;
}

Have b variable and a variable, GCC compiler always read a variable from Dbus, but when not initialed yet, there is no value 0x55, so I hope GCC compiler can initial 0x55 value into mem_data region.有 b 变量和 a 变量,GCC 编译器总是从 Dbus 中读取一个变量,但是当还没有初始化时,没有值 0x55,所以我希望 GCC 编译器可以将 0x55 值初始化到 mem_data 区域。

I use riscv-none-embed-gcc to generator code for test, and i use ld want to set up memory address.我使用 riscv-none-embed-gcc 生成代码进行测试,我使用 ld 想要设置内存地址。

command:命令:

riscv-none-embed-gcc -lc -nostdlib  -O3 -march=rv32im  -T test.ld TEST.c -o TEST.o -lg -lgloss -mcmodel=medlow 
riscv-none-embed-objcopy -O verilog "TEST.o"  "TEST.vn"
riscv-none-embed-objdump --disassemble-all -S -d TEST.o > TEST.lst 

At ld file I set up program memory and data memory ORIGIN and put data in data memory.在 ld 文件中,我设置了程序存储器和数据存储器 ORIGIN 并将数据放入数据存储器中。

ld: ld:

OUTPUT_ARCH( "riscv" )

MEMORY {
  mem_text (rx) : ORIGIN = 0x00000000, LENGTH = 0x1000000   // This is program memory ORIGIN that I set.
  mem_data (rw) : ORIGIN = 0x20000000, LENGTH = 0x1000000   // This is data memory ORIGIN that I set.
}

SECTIONS
{
  . = 0x00000000;
 
  .text : { *(.text) } > mem_text  // Put code in program memory.

  . = 0x20000000;
  .data : {
    *(.sdata)
  } > mem_data   // Put data in data memory.
}

After generate I get this, the b variable at mem_data region but a is not, there different is a variable is in main function.生成后我得到了这个,mem_data 区域的 b 变量但 a 不是,不同的是一个变量在 main 函数中。

TEST.o:     file format elf32-littleriscv


Disassembly of section .text.startup:

00000000 <main>:
   0:   000047b7            lui a5,0x4
   4:   05500713            li  a4,85
   8:   00e7a023            sw  a4,0(a5) # 4000 <main+0x4000>
   c:   20000737            lui a4,0x20000
  10:   00072703            lw  a4,0(a4) # 20000000 <b>
  14:   00e7a223            sw  a4,4(a5)
  18:   00008067            ret

Disassembly of section .data:

20000000 <b>:
20000000:   0035                    c.nop   13   // b variable at mem_data region but a is not

I convert to machine code, we can see the same thing b variable at mem_data region but a is not.我转换为机器代码,我们可以在 mem_data 区域看到相同的 b 变量,但 a 不是。

So how can I initial 0x55 value into mem_data region?那么如何将初始 0x55 值放入 mem_data 区域?

@00000000
B7 47 00 00 13 07 50 05 23 A0 E7 00 37 07 00 20 
03 27 07 00 23 A2 E7 00 67 80 00 00 
@20000000
35 00 00 00   // b variable at mem_data region but a is not.

I change my ld but still no change at machine code.我改变了我的 ld 但机器代码仍然没有改变。

OUTPUT_ARCH( "riscv" )

MEMORY {
  mem_text (rx) : ORIGIN = 0x00000000, LENGTH = 0x1000000   
  mem_data (rw) : ORIGIN = 0x20000000, LENGTH = 0x1000000   
}

SECTIONS
{
  . = 0x00000000;
 
  .text : { *(.text) } > mem_text  

  . = 0x20000000;
  .data : {
    *(.sdata)
  } > mem_data at > mem_text
}
TEST.o:     file format elf32-littleriscv


Disassembly of section .text.startup:

00000000 <main>:
   0:   000047b7            lui a5,0x4
   4:   05500713            li  a4,85
   8:   00e7a023            sw  a4,0(a5) # 4000 <main+0x4000>
   c:   20000737            lui a4,0x20000
  10:   00072703            lw  a4,0(a4) # 20000000 <b>
  14:   00e7a223            sw  a4,4(a5)
  18:   00008067            ret

Disassembly of section .data:

20000000 <b>:
20000000:   0035                    c.nop   13
@00000000
B7 47 00 00 13 07 50 05 23 A0 E7 00 37 07 00 20 
03 27 07 00 23 A2 E7 00 67 80 00 00 
@0000001C
35 00 00 00 

Your question isn't very clear, so allow me to reformulate and correct me if I am wrong :你的问题不是很清楚,所以如果我错了,请允许我重新表述并纠正我:

You have a global variable b that is stored and initialised in the mem_data region, and you want your local a variable to also be stored and initialised in the mem_data region.您有一个在mem_data区域中存储和初始化的全局变量b ,并且您希望在mem_data区域中也存储和初始化您a本地变量。

If we convert the assembly back to a C-like pseudocode, it looks like this :如果我们将程序集转换回类似 C 的伪代码,它看起来像这样:

int b = 0x35;

void main()
{
    const int *address = 0x4000;

    a5 = 0x4000;      //  0:   lui a5,0x4
    a4 = 0x55;        //  4:   li  a4,85
    address[a5] = a4; //  8:   sw  a4,0(a5)
    a4 = &b;          //  c:   lui a4,0x20000
    a4 = *a4;         // 10:   lw  a4,0(a4)
    a5[4] = a4;       // 14:   sw  a4,4(a5)
    return;           // 18:   ret
}

You can see that the variable a is never stored in memory but its value is still used.您可以看到变量a从未存储在内存中,但它的值仍在使用中。 This is caused by the optimisation, and the storage class of the variable.这是由优化和变量的存储类引起的。 Variables declared outside of a function are static , meaning they will always have the same address.在函数外部声明的变量是static的,这意味着它们将始终具有相同的地址。 This is the case of b .这是b的情况。 a on the other hand has an automatic storage duration . a另一方面具有自动存储持续时间

Automatic variables are stored on the stack, and only exist for the duration of the function/scope they are declared in. Because a function can be recursively called, a new variable is created every time the function is called.自动变量存储在堆栈中,并且仅在声明它们的函数/范围内存在。因为可以递归调用函数,所以每次调用函数时都会创建一个新变量。 This means it cannot have a fixed address and that's why it wont have a dedicated address in mem_data , instead it will have an address on the stack and will be initialised at runtime.这意味着它不能有一个固定的地址,这就是为什么它不会在mem_data中有一个专用地址,而是它将在堆栈上有一个地址,并将在运行时初始化。

This explains why it doesn't have an address, but it doesn't explain why it isn't stored in memory.这解释了为什么它没有地址,但没有解释为什么它没有存储在内存中。 That is caused by optimisation.这是由优化引起的。 The compiler is clever enough to understand that your variable has a value that is immediately used after.编译器足够聪明,可以理解您的变量具有之后立即使用的值。 So instead of wasting time to store it, load it and then use it, it will simply use the value and never declare the variable.因此,与其浪费时间存储它、加载它然后使用它,它只会使用该值而从不声明变量。

In short, a is not stored in memory because it an auto variable and the compiler optimise it out.简而言之, a 没有存储在内存中,因为它是一个auto变量,编译器对其进行了优化。


So your options are the following :所以你的选择如下:

  • If you want to ensure the variable is stored in memory, declare it with volatile .如果要确保变量存储在内存中,请使用volatile声明它。 It makes sure the compiler loads the data from memory every time it needs it, and can greatly reduce performance.它确保编译器在每次需要时从内存中加载数据,并且会大大降低性能。 That's used for variables that may change in a way the compiler don't expect it, like peripheral registers in microcontrollers.这用于可能以编译器不期望的方式更改的变量,例如微控制器中的外围寄存器。 You probably don't need that here.你可能在这里不需要那个。

  • If you want it to have a dedicated address and have it initialised like b , but still only be visible in main() , declare it with static .如果您希望它有一个专用地址并像b一样初始化它,但仍然只在main()中可见,请使用static声明它。 That's the option you should probably chose if you want a to behave like b .如果您希望a表现得像b ,那么这就是您可能应该选择的选项。

  • If none of the above really matter, let the compiler optimise it for you.如果以上都不重要,让编译器为您优化它。 That's most probably what you really need.这很可能是你真正需要的。

Note that setting a to static apparently won't place it in the memory for you simple program even with optimisation at the lowest, at least with my version of riscv32-gcc.请注意,将a设置为static显然不会为您的简单程序将其放入内存中,即使优化程度最低,至少在我的 riscv32-gcc 版本中是这样。 If I declare it with static volatile , it appears in mem_data :如果我用static volatile声明它,它会出现在mem_data中:

00011a08 <b>:
   11a08:   0035                    .2byte  0x35
    ...

00011a0c <a.0>:
   11a0c:   0055                    .2byte  0x55
    ...

Only do it for testing purposes, otherwise it will impact performance.仅出于测试目的进行,否则会影响性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 查找主函数局部变量的地址 - Finding the address of a main function local variable buf的地址是什么(主函数中的局部变量)? - What is the address of buf (the local variable in the main function)? 将本地指针变量的地址返回给main()函数 - Returning an address of a local pointer variable to main() function 如何通过访问其 memory 地址将局部变量从一个线程传递到另一个线程? - how can I pass an local variable from a thread to another thread by accessing its memory address? 如何在GCC的绝对地址处声明变量? - How can I declare a variable at an absolute address with GCC? 返回局部变量地址的Function与不同版本的gcc的行为不同? - Function that returns address of local variable acts differently with different versions of gcc? 如何设置Visual Studio以了解GCC定义? - How can I set up Visual Studio to understand GCC defines? 在 C 中,我理解为什么不在指针返回函数中返回局部变量的地址,但我该如何解决? - In C, I understand why not to return the address of a local variable in a pointer returning function, how can I fix it though? 如何判断函数何时访问局部变量或外部变量? - How can I tell when a function is accessing a local or external variable? 在主要和功能上打印时变量地址的差异 - Difference in address of variable when printing in main and in a function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM