int *和char *写入内存

时间:2015-11-24 13:02:38

标签: c nios

我最近学习了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

1 个答案:

答案 0 :(得分:2)

这是我根据观察到的行为进行的推测。

您的存储设备由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添加到指针中的地址,因此地址序列int存储如上所述。

如果使用char指针存储字符,则每次递增char指针时,C指针算术会将sizeof(char) = 1添加到指针中的地址。代码尝试将前四个字符(0,1,2,3)存储到MEMORY_0_BASE + 0MEMORY_0_BASE + 1MEMORY_0_BASE + 2MEMORY_0_BASE + 3。如果我相信指针的底部两位被屏蔽,那么所有这些地址都存储到MEMORY_0_BASE,并且当你完成时,它的值是3。

类似于后四个字符(4,5,6,7)。它们会存储到MEMORY_0_BASE + 4MEMORY_0_BASE + 5MEMORY_0_BASE + 6MEMORY_0_BASE + 7,这些都会在屏蔽后映射到MEMORY_0_BASE + 4,并使其包含数字7,依此类推。

这就是你如何得到序列3,3,3,3,7,7,7,7,11,11,11,11,15,15,15,15。