联合在另一个函数中读取错误的内存位置

发布于 2025-02-04 12:38:59 字数 4218 浏览 3 评论 0 原文

#include <stdio.h>
#include <string.h>
enum ACTION {RD = 0 , WR = 1};
enum SIZE {B = 1, W = 2};

union memory{//Memory union since space is limited
    unsigned char byte[0x10000];
    unsigned short word[0x8000];
};
union word_byte{//Ability to access either a word or byte and save memory space
    unsigned short word;
    unsigned char byte[2];
};

void bus(unsigned short, unsigned short* , enum ACTION, enum SIZE);


void print(unsigned short, unsigned short*);

int main() {
    FILE* file;
    enum ACTION act;
    enum SIZE sz;;
    unsigned short addr, idata;
    char rdwr[256], wb[256];
    file = fopen("test.txt", "r");
    while (fscanf(file,"%hx %hx %s %s", &addr, &idata, rdwr, wb) != EOF)
    {
        printf("%x %x %s %s\n", addr, idata, rdwr, wb);//Read in address and byte
        if(*rdwr == 'R')//If it is reading
        {
            act = RD;
        }
        else// else writing
        {
            act = WR;
        }
        if(*wb == 'B')//If byte
        {
            sz = B;
        }
        else//Else word
        {
            sz = W;
        }

        if(act == RD && sz == W)//If read and word must execute an insturction since removed the execution but still prints byte locations
        {
            bus(addr, &idata, act, sz);
            print(addr, &idata);
        }else//Just send it to the bus to be written into union memory
        {
            bus(addr, &idata, act, sz);
        }
    }

    return 0;
}
/*
BUS function description
MAR is the address and *mbr is the data being either read or written with enums for selection
The bus function is used to access memory for this problem and allows for the reading or writing
of a byte or word
*/
void bus(unsigned short mar, unsigned short *mbr, enum ACTION rw, enum SIZE bw){
    union memory mem;
    if(rw == 0)
    {
        if(bw == 1)
        {
            *mbr = mem.byte[mar];
            printf("READ BYTE:%hx\n", *mbr);
        
        }
        else
        {
            mar = mar>>1;
            *mbr = (mem.word[mar] << 8) | (mem.word[mar+1]);
            printf("READ WORD: %hx\n", *mbr);
        }
    }
    else
    {
        if(bw == 1)
        {
            printf("MAR %hx, MBR %hx\n", mar, *mbr);
            mem.byte[mar] = *mbr & 0xFF;
            printf("Byte Write: %hx\n", mem.byte[mar]);
        }
        else
        {
            mar = mar >> 1;
            printf("MAR %hx, MBR %hx\n", mar, *mbr);
            mem.word[mar] = *mbr & 0xFF;
            printf("%hx Word Write: %hx\n",mar,  mem.word[mar]);
        }
    }
}
/*
PRINT function below description
Function for later on to manipulate memory and access it 
I do not understand where the extra 0x10 addition is coming into play?
*/
void print(unsigned short mar, unsigned short *mbr)
{
    union memory mem;
    int j = 0, k = 0;

        for(j = 0; j<=0xFF; j++)//For printing low address to check where the byte actually is.
            {
                
                *mbr = mem.byte[j];
                if(*mbr == 0)
                {
                    printf("");
                }else
                {
                    printf("j: %hx *MBR: %hx\n",j, *mbr);
                }
                
            }
}
    

输入文件test.txt

007F AB W B
0080 CD W B
3005 94 W W 
3006 01 W W
3005 0 R W
007F 0 R B

输出CMD

7f ab W B
MAR 7f, MBR ab
Byte Write: ab
80 cd W B
MAR 80, MBR cd
Byte Write: cd
3005 94 W W
MAR 1802, MBR 94
1802 Word Write: 94
3006 1 W W
MAR 1803, MBR 1
1803 Word Write: 1
3005 0 R W
READ WORD: 9401
j: 8 *MBR: 2
j: 8f *MBR: ab
j: 90 *MBR: cd
7f 0 R B
READ BYTE:ab

我昨晚发布了此消息,但意识到我可以压实它以找到我的错误。该程序适用于我的任务是读取地址和数据以及两个命令。第一个命令决定是否应读取或编写数据(R或W),而第二个命令则指示数据是单词还是字节(W或B)。这一切都传递给了应该写入内存的总线功能。如果碰巧有r和w(读单词),程序应执行指令。由于工会中的特定错误,我还没有走那么远,所以现在我只打印字节的内存位置。如我的输入所示,我指定字节AB应在内存位置007F或7F,因为编译器未打印00。现在找到字节AB在内存中的位置。令我惊讶的是,在8F处,比我指定的本为0x10。但是,当我在总线函数中读取单词,如输入的最后一行所示,它会在7F处读取字节?内存增加是否是由于函数打印中联合内存的另一个调用而发生的?如果需要更多信息,我很乐意为您提供帮助。

请忽略K:8 *MBR:2是我系统中未归零的随机内存位置!

谢谢!

#include <stdio.h>
#include <string.h>
enum ACTION {RD = 0 , WR = 1};
enum SIZE {B = 1, W = 2};

union memory{//Memory union since space is limited
    unsigned char byte[0x10000];
    unsigned short word[0x8000];
};
union word_byte{//Ability to access either a word or byte and save memory space
    unsigned short word;
    unsigned char byte[2];
};

void bus(unsigned short, unsigned short* , enum ACTION, enum SIZE);


void print(unsigned short, unsigned short*);

int main() {
    FILE* file;
    enum ACTION act;
    enum SIZE sz;;
    unsigned short addr, idata;
    char rdwr[256], wb[256];
    file = fopen("test.txt", "r");
    while (fscanf(file,"%hx %hx %s %s", &addr, &idata, rdwr, wb) != EOF)
    {
        printf("%x %x %s %s\n", addr, idata, rdwr, wb);//Read in address and byte
        if(*rdwr == 'R')//If it is reading
        {
            act = RD;
        }
        else// else writing
        {
            act = WR;
        }
        if(*wb == 'B')//If byte
        {
            sz = B;
        }
        else//Else word
        {
            sz = W;
        }

        if(act == RD && sz == W)//If read and word must execute an insturction since removed the execution but still prints byte locations
        {
            bus(addr, &idata, act, sz);
            print(addr, &idata);
        }else//Just send it to the bus to be written into union memory
        {
            bus(addr, &idata, act, sz);
        }
    }

    return 0;
}
/*
BUS function description
MAR is the address and *mbr is the data being either read or written with enums for selection
The bus function is used to access memory for this problem and allows for the reading or writing
of a byte or word
*/
void bus(unsigned short mar, unsigned short *mbr, enum ACTION rw, enum SIZE bw){
    union memory mem;
    if(rw == 0)
    {
        if(bw == 1)
        {
            *mbr = mem.byte[mar];
            printf("READ BYTE:%hx\n", *mbr);
        
        }
        else
        {
            mar = mar>>1;
            *mbr = (mem.word[mar] << 8) | (mem.word[mar+1]);
            printf("READ WORD: %hx\n", *mbr);
        }
    }
    else
    {
        if(bw == 1)
        {
            printf("MAR %hx, MBR %hx\n", mar, *mbr);
            mem.byte[mar] = *mbr & 0xFF;
            printf("Byte Write: %hx\n", mem.byte[mar]);
        }
        else
        {
            mar = mar >> 1;
            printf("MAR %hx, MBR %hx\n", mar, *mbr);
            mem.word[mar] = *mbr & 0xFF;
            printf("%hx Word Write: %hx\n",mar,  mem.word[mar]);
        }
    }
}
/*
PRINT function below description
Function for later on to manipulate memory and access it 
I do not understand where the extra 0x10 addition is coming into play?
*/
void print(unsigned short mar, unsigned short *mbr)
{
    union memory mem;
    int j = 0, k = 0;

        for(j = 0; j<=0xFF; j++)//For printing low address to check where the byte actually is.
            {
                
                *mbr = mem.byte[j];
                if(*mbr == 0)
                {
                    printf("");
                }else
                {
                    printf("j: %hx *MBR: %hx\n",j, *mbr);
                }
                
            }
}
    

Input file test.txt

007F AB W B
0080 CD W B
3005 94 W W 
3006 01 W W
3005 0 R W
007F 0 R B

Output in cmd

7f ab W B
MAR 7f, MBR ab
Byte Write: ab
80 cd W B
MAR 80, MBR cd
Byte Write: cd
3005 94 W W
MAR 1802, MBR 94
1802 Word Write: 94
3006 1 W W
MAR 1803, MBR 1
1803 Word Write: 1
3005 0 R W
READ WORD: 9401
j: 8 *MBR: 2
j: 8f *MBR: ab
j: 90 *MBR: cd
7f 0 R B
READ BYTE:ab

I posted this last night, but realize I can compact it to find my error. The program is for a class that my task is to read an address and data in along with two commands. The first command dictate whether the data should be read or written (R or W), while the second command dictates if the data is a word or byte (W or B). This all gets passed to the bus function which should write to memory. If there happens to be a R and W (read word) the program should execute an instruction. I haven't gotten that far due to a specific error in my unions so for now I just print the memory locations of the bytes. As seen by my input I specify the byte AB should be at the memory location 007F or 7F since the compiler doesn't print the 00. Later on when calling my print function I print out all memory locations rangining from 00 to FF in a attempt to now find where the byte AB is in memory. To my suprise it is at 8F which is 0x10 more then what I specified it to be written as. Yet when I do a read word in the bus function as shown in the last line of the input it reads the byte at 7f? Does the memory increase happen due to another call of the union memory in the function print? If more info is needed I would be happy to help.

Please ignore k:8 *MBR: 2 that is a random memory location not zeroed in my system!

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心奴独伤 2025-02-11 12:38:59

函数 BUS print 中的行

union memory mem;

中的行分配一个本地数组,大小为64 kib

因为它是一个non- static static local数组, lifetime 仅与声明其声明的函数一样长。因此,功能 BUS 打印不使用同一数组。

解决此问题的最简单解决方案是删除两个声明,并将数组声明为全局变量,而是这样:

union memory{//Memory union since space is limited
    unsigned char byte[0x10000];
    unsigned short word[0x8000];
} mem;

这样,当它们使用标识符 mem 时,所有函数都将使用相同的数组。 。

另外,您可以将数组声明为 main 中的本地数组,并在调用函数 BUS print /代码>。通常,这被认为是比使用全局变量更好的编程样式。

进一步的问题:

您应该检查 fopen 的返回值并打印错误消息并在程序失败时终止,例如:

file = fopen("test.txt", "r");
if ( file == NULL )
{
    fprintf( stderr, "Error opening file!\n" );
    exit( EXIT_FAILURE );
}

请注意,您必须<<<代码> #include&lt; stdlib.h&gt; 为了使用函数 exit

该行

while (fscanf(file,"%hx %hx %s %s", &addr, &idata, rdwr, wb) != EOF)

可能应该更改为,

while ( fscanf(file,"%hx %hx %s %s", &addr, &idata, rdwr, wb) == 4 )

因为如果并非所有参数都可以匹配,您可能想停止。

The line

union memory mem;

in the function bus and print will allocate a local array with the size of 64 KiB.

Since it is a non-static local array, the lifetime of this array is only as long as the function in which it is declared. Therefore, the functions bus and print are not using the same array.

The simplest fix to this problem would be to remove both declarations and to declare the array as a global variable instead, like this:

union memory{//Memory union since space is limited
    unsigned char byte[0x10000];
    unsigned short word[0x8000];
} mem;

That way, all functions would be using the same array when they use the identifier mem.

Alternatively, you could declare the array as a local array in main and pass a pointer to the array as an additional parameter whenever you call the functions bus and print. This is generally considered better programming style than using global variables.

Further issues:

You should check the return value of fopen and print an error message and terminate the program if it fails, for example like this:

file = fopen("test.txt", "r");
if ( file == NULL )
{
    fprintf( stderr, "Error opening file!\n" );
    exit( EXIT_FAILURE );
}

Note that you will have to #include <stdlib.h> in order to use the function exit.

The line

while (fscanf(file,"%hx %hx %s %s", &addr, &idata, rdwr, wb) != EOF)

should probably be changed to

while ( fscanf(file,"%hx %hx %s %s", &addr, &idata, rdwr, wb) == 4 )

because you probably want to stop if not all arguments could be matched.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文