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 + 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。