[英]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.