int* 和 char* 写入内存
int* and char* to write into memory
最近学习nios II SOPC,遇到了内存写入和读取的过程。指针 int* 和 char* 的使用让我得到了两个不同的结果。代码如下
#include "system.h"
#include "stdio.h"
int main()
{
char* n = (char*) MEMORY_0_BASE; //the address for first block of memory
int i;
for(i=0;i<16;i++)
{
*(n+i)=i;
}
for(i=0;i<16;i++)
{
printf("Du lieu tai o nho thu %d la %d\n", i , *(n+i));
}
while(1);
}
"int*"的代码如下
#include "system.h"
#include "stdio.h"
int main()
{
char* n = (char*) MEMORY_0_BASE; //the address for first block of memory
int i;
for(i=0;i<16;i++)
{
*(n+i)=i;
}
for(i=0;i<16;i++)
{
printf("Du lieu tai o nho thu %d la %d\n", i , *(n+i));
}
while(1);
}
使用 "int*" 的结果是 0,1,2,...,15 而 "char*" 的结果是 3,3,3,3,7,7,7, 7、11、11、11、11、15、15、15、15。我无法解释为什么会这样。
下面是我对内存块的代码
module memory
#(parameter DATA_WIDTH=32, parameter ADDR_WIDTH=4)
(
input iClk, iReset_n,
input iRead_n, iWrite_n,
input [ADDR_WIDTH-1:0] iAddress,
input [DATA_WIDTH-1:0] iData,
output [DATA_WIDTH-1:0] oData
);
reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_reg;
always@(posedge iClk)
begin
if(!iWrite_n)
mem[iAddress] = iData;
if(!iRead_n)
addr_reg = iAddress;
end
assign oData = mem[addr_reg];
endmodule
这是我根据观察到的行为做出的推测。
您的存储设备由 16 x 32 位整数组成。我的猜测是,喜欢以字节为单位寻址的编译器有效地屏蔽了地址的最低两位。第零个寄存器的地址为 MEMORY_0_BASE + 0 * 4
,第一个寄存器的地址为 MEMORY_0_BASE + 1 * 4
,第二个寄存器的地址为 MEMORY_0_BASE + 2 * 4
等
如果使用 int 指针将 int 存储到寄存器,每次递增 int 指针时,C 指针算法实际上将 sizeof(int)
= 4 添加到指针中的地址,因此地址序列存储整数的地方如上所述。
如果使用 char 指针存储 char,每次递增 char 指针时,C 指针算法都会将 sizeof(char)
= 1 添加到指针中的地址。该代码尝试将前四个字符 (0、1、2、3) 存储到 MEMORY_0_BASE + 0
、MEMORY_0_BASE + 1
、MEMORY_0_BASE + 2
、MEMORY_0_BASE + 3
。如果,正如我所相信的那样,指针的底部两位被屏蔽,所有这些地址存储到 MEMORY_0_BASE
并且,当你完成时,它的值是 3.
后四个字符 (4, 5, 6, 7) 同样如此。它们被存储到 MEMORY_0_BASE + 4
、MEMORY_0_BASE + 5
、MEMORY_0_BASE + 6
、MEMORY_0_BASE + 7
,它们在屏蔽后都映射到 MEMORY_0_BASE + 4
,留下它包含数字 7 等等。
这就是你如何得到序列 3,3,3,3,7,7,7,7,11,11,11,11,15,15,15,15。
最近学习nios II SOPC,遇到了内存写入和读取的过程。指针 int* 和 char* 的使用让我得到了两个不同的结果。代码如下
#include "system.h"
#include "stdio.h"
int main()
{
char* n = (char*) MEMORY_0_BASE; //the address for first block of memory
int i;
for(i=0;i<16;i++)
{
*(n+i)=i;
}
for(i=0;i<16;i++)
{
printf("Du lieu tai o nho thu %d la %d\n", i , *(n+i));
}
while(1);
}
"int*"的代码如下
#include "system.h"
#include "stdio.h"
int main()
{
char* n = (char*) MEMORY_0_BASE; //the address for first block of memory
int i;
for(i=0;i<16;i++)
{
*(n+i)=i;
}
for(i=0;i<16;i++)
{
printf("Du lieu tai o nho thu %d la %d\n", i , *(n+i));
}
while(1);
}
使用 "int*" 的结果是 0,1,2,...,15 而 "char*" 的结果是 3,3,3,3,7,7,7, 7、11、11、11、11、15、15、15、15。我无法解释为什么会这样。
下面是我对内存块的代码
module memory
#(parameter DATA_WIDTH=32, parameter ADDR_WIDTH=4)
(
input iClk, iReset_n,
input iRead_n, iWrite_n,
input [ADDR_WIDTH-1:0] iAddress,
input [DATA_WIDTH-1:0] iData,
output [DATA_WIDTH-1:0] oData
);
reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_reg;
always@(posedge iClk)
begin
if(!iWrite_n)
mem[iAddress] = iData;
if(!iRead_n)
addr_reg = iAddress;
end
assign oData = mem[addr_reg];
endmodule
这是我根据观察到的行为做出的推测。
您的存储设备由 16 x 32 位整数组成。我的猜测是,喜欢以字节为单位寻址的编译器有效地屏蔽了地址的最低两位。第零个寄存器的地址为 MEMORY_0_BASE + 0 * 4
,第一个寄存器的地址为 MEMORY_0_BASE + 1 * 4
,第二个寄存器的地址为 MEMORY_0_BASE + 2 * 4
等
如果使用 int 指针将 int 存储到寄存器,每次递增 int 指针时,C 指针算法实际上将 sizeof(int)
= 4 添加到指针中的地址,因此地址序列存储整数的地方如上所述。
如果使用 char 指针存储 char,每次递增 char 指针时,C 指针算法都会将 sizeof(char)
= 1 添加到指针中的地址。该代码尝试将前四个字符 (0、1、2、3) 存储到 MEMORY_0_BASE + 0
、MEMORY_0_BASE + 1
、MEMORY_0_BASE + 2
、MEMORY_0_BASE + 3
。如果,正如我所相信的那样,指针的底部两位被屏蔽,所有这些地址存储到 MEMORY_0_BASE
并且,当你完成时,它的值是 3.
后四个字符 (4, 5, 6, 7) 同样如此。它们被存储到 MEMORY_0_BASE + 4
、MEMORY_0_BASE + 5
、MEMORY_0_BASE + 6
、MEMORY_0_BASE + 7
,它们在屏蔽后都映射到 MEMORY_0_BASE + 4
,留下它包含数字 7 等等。
这就是你如何得到序列 3,3,3,3,7,7,7,7,11,11,11,11,15,15,15,15。