变量在使用赋值语句赋值后恢复为以前的值



我正在编写一个简单的chip8模拟器。

我有一个值叫做程序计数器(PC(。

问题是,一旦我从修改 PC 的指令 1((返回,PC 就会返回到被该方法修改之前的值。

在指令 1 分配给 PC 之前,PC 的值为 203。

在指令 1 之后,PC 的值为 (0x0NNN & 0xFFFE(。

通过程序计数器++,它返回到203而不是增量。

#include <cstdint>
constexpr auto PROGRAMSTART = 0x200;
constexpr auto GRAPHICSTART = 0xF00;
constexpr auto GRAPHICEND = 0xFFF;
//Memory
static uint8_t memory[4096]; // 0x000-0xFFF -> 0000-4095
static uint16_t stack[16];
//General Purpose Registers
static uint8_t registers[16]; //Register V0,V1,..V9,VA,VB,..,VF
//Special Purpose Register
static uint8_t specialRegisters[2];
static uint8_t stackPointer;
static uint16_t registerI;
static uint16_t programCounter = PROGRAMSTART;
//Graphic
const int WIDTH = 64;
const int HEIGHT = 32;
const int beginnningOfGraphicMemory = 0xF00;

对于指令 1NNN("https://en.wikipedia.org/wiki/CHIP-8#Opcode_table"(, 这是一个简单的无条件跳跃。

void Instruction1(uint16_t NNN)
{
programCounter = (NNN & 0xFFFE); //Keeps the PC counter aligned to memory
}
int main()
{
SetUpInterpreterText(0);
Test();
for (;;)
{
printf("Program Counter: %04x n", programCounter);
uint16_t byte0 = (memory[programCounter++] << 8);
uint16_t byte1 = (memory[programCounter]);
uint16_t instruction = byte0 + byte1; //must load data in 16bit chunks
Decoder(instruction);
printf("Program Counter: %04x  Data: %04x n", programCounter, instruction);
programCounter++;

}
return 0;
}
void Decoder(uint16_t instruction)
{
uint16_t data = instruction & 0x0FFF; //removing the top 4 bits to make it easier
switch (instruction >> 12)
{
case 0:
Instruction0(data);
break;
case 1:
Instruction1(data);
break;
default:
std::cout << "Instruction Not Foud" << std::endl;
exit(EXIT_FAILURE);
break;
}
}

解码器所做的只是删除 16 位指令指令的前 4 位。例如,0x1234被发送到 1NNN 指令/方法,234 表示指令的 NNN 部分。

我拆解了程序,根据组装, PC存储在内存中,一旦我进入"程序计数器++",它就会从内存中恢复。但是,对于指令 1,它不会将寄存器 EAX 的权限写入内存。

我应该怎么做才能让编译器知道我希望它在为它分配值时更新 PC 的内存位置,而不仅仅是更新寄存器?

附言 我尝试过编写内联程序集,但我对 x86 程序集并不熟练。我似乎无法register_EAX移动到该值的内存位置,因此我可以强制更新值,因为 EAX 在 PC 递增之前具有适当的值。

您有两个或多个 cpp 文件。 每个组成一个编译单元。 (包含的.h单独成为每个编译单元的一部分;编译单元的概念在预处理完成后适用。

静态全局变量在编译单元之间没有链接,它们是私有的,它们在其中定义它们的单元.
static uint16_t programCounter因此是每个 cpp 文件的本地变量。

作为一般规则:

  1. 停止使用全局变量,尤其是可变变量。 显式传递共享状态。 使用类或结构。
  2. 特别是停止在头文件中使用可变静态变量。 这太疯狂了。
  3. 当事情没有意义时检查数据的地址。

请注意,static在类和函数中具有与它在全局范围内具有不同的含义。 常规全局变量已具有静态存储类(与static变量相同(,但具有全局跨文件可见性。

最新更新