变量在使用赋值语句赋值后恢复到以前的值
A variable is reverting to a previous value after being assigned to with an assignment statement
我正在写一个简单的 chip8 模拟器。
我有一个名为 programCounter(PC) 的值。
问题是,一旦我从 Instruction1(修改 PC)return,PC returns 变成了被方法修改之前的值。
例子
Instruction1赋值给PC之前,PC的值为203
Instruction1后,PC的值为(0x0NNN & 0xFFFE)。
通过programCounter++,它比增量return到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 instruction/Method 并且 234 表示指令的 NNN 部分。
我把程序反汇编了一下,按照汇编,
PC 存储在内存中,一旦我进入“programCounter++”;它是从内存中恢复的。但是,对于 Instruction1,它不会写入内存,而是写入寄存器 EAX。
我应该怎么做才能让编译器知道我希望它在我为它赋值时更新 PC 的内存位置而不是仅仅更新寄存器?
P.S。
我曾尝试编写内联汇编,但我不擅长 x86 汇编。我似乎无法将 register_EAX 移动到值的内存位置,因此我可以强制更新值,因为 EAX 具有正确的值,直到 PC 递增。
您有两个或多个 cpp 文件。每一个组成一个编译单元。 (您包含的 .h
分别成为每个编译单元的一部分;编译单元的概念适用 在 预处理完成后。)
静态全局变量不在编译单元之间链接,它们对于定义它们的单元是私有的。
static uint16_t programCounter
因此对于每个 cpp 文件都是本地的。
一般规则:
- 停止使用全局变量,尤其是可变变量。显式传递共享状态。使用 class 或结构。
- 特别是停止在头文件中使用可变静态变量。太疯狂了。
- 当事情没有意义时检查数据的地址。
请注意,static
在 class 中的含义和它在全局范围内的功能不同。常规全局变量已经具有静态 存储 class(与 static
变量相同),但具有全局跨文件可见性。
我正在写一个简单的 chip8 模拟器。
我有一个名为 programCounter(PC) 的值。
问题是,一旦我从 Instruction1(修改 PC)return,PC returns 变成了被方法修改之前的值。
例子
Instruction1赋值给PC之前,PC的值为203
Instruction1后,PC的值为(0x0NNN & 0xFFFE)。
通过programCounter++,它比增量return到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 instruction/Method 并且 234 表示指令的 NNN 部分。
我把程序反汇编了一下,按照汇编, PC 存储在内存中,一旦我进入“programCounter++”;它是从内存中恢复的。但是,对于 Instruction1,它不会写入内存,而是写入寄存器 EAX。
我应该怎么做才能让编译器知道我希望它在我为它赋值时更新 PC 的内存位置而不是仅仅更新寄存器?
P.S。 我曾尝试编写内联汇编,但我不擅长 x86 汇编。我似乎无法将 register_EAX 移动到值的内存位置,因此我可以强制更新值,因为 EAX 具有正确的值,直到 PC 递增。
您有两个或多个 cpp 文件。每一个组成一个编译单元。 (您包含的 .h
分别成为每个编译单元的一部分;编译单元的概念适用 在 预处理完成后。)
静态全局变量不在编译单元之间链接,它们对于定义它们的单元是私有的。
static uint16_t programCounter
因此对于每个 cpp 文件都是本地的。
一般规则:
- 停止使用全局变量,尤其是可变变量。显式传递共享状态。使用 class 或结构。
- 特别是停止在头文件中使用可变静态变量。太疯狂了。
- 当事情没有意义时检查数据的地址。
请注意,static
在 class 中的含义和它在全局范围内的功能不同。常规全局变量已经具有静态 存储 class(与 static
变量相同),但具有全局跨文件可见性。