Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
标签大小不固定时如何处理正向引用 我试图在C++中编写8086模拟器。 但我面临一个问题_C++_Assembly_X86_Emu8086 - Fatal编程技术网

标签大小不固定时如何处理正向引用 我试图在C++中编写8086模拟器。 但我面临一个问题

标签大小不固定时如何处理正向引用 我试图在C++中编写8086模拟器。 但我面临一个问题,c++,assembly,x86,emu8086,C++,Assembly,X86,Emu8086,假设代码为: MOV AL, BL JMP X MOV BL, CL MOV DL, CL . . . X: ADD AX, BX HLT 现在,JMPX的机器代码将取决于X,不管它是否是 近:8位地址[00 ff] short:16位地址(ff ffff) 因此,如果JMP指令的大小过去是常数(固定大小),那么我可以进一步移动,每当我找到X时,我就可以把它的地址放回去。 但在这里我不能再进一步了,因为下一个位置也取决于JMPX,而且它的大小不是固定的 我不知道如何处理它。对于jmp,您可能会

假设代码为:

MOV AL, BL
JMP X
MOV BL, CL
MOV DL, CL
.
.
.
X:
ADD AX, BX
HLT
现在,JMPX的机器代码将取决于X,不管它是否是

近:8位地址[00 ff]

short:16位地址(ff ffff)

因此,如果JMP指令的大小过去是常数(固定大小),那么我可以进一步移动,每当我找到X时,我就可以把它的地址放回去。 但在这里我不能再进一步了,因为下一个位置也取决于JMPX,而且它的大小不是固定的


我不知道如何处理它。

对于
jmp
,您可能会遇到更多问题。请参阅以下可能的操作码及其含义:

EB cb   JMP rel8        Jump short, relative, displacement relative to next instruction.
E9 cw   JMP rel16       Jump near, relative, displacement relative to next instruction.
E9 cd   JMP rel32       Jump near, relative, displacement relative to next instruction.
FF /4   JMP r/m16       Jump near, absolute indirect, address given in r/m16.
FF /4   JMP r/m32       Jump near, absolute indirect, address given in r/m32.
EA cd   JMP ptr16:16    Jump far, absolute, address given in operand.
EA cp   JMP ptr16:32    Jump far, absolute, address given in operand.
FF /5   JMP m16:16      Jump far, absolute indirect, address given in m16:16.
FF /5   JMP m16:32      Jump far, absolute indirect, address given in m16:32.
<>所以,你需要考虑更多的特殊情况。

解决方案是实现一个多程汇编程序。您需要将所有操作码和操作数存储在
std::vector
或任何地方。然后您可以在第二步中设置正确的数据

如果为操作码和操作数定义一个
struct
,并将所有这些结构存储在
std::vector
中,它将不会对其他操作码/操作数产生影响。您还可以运行多个过程,直到一切正常

然后,当所有事情都解决后,您可以再次检查
std::vector
,并发出真正需要的数据

你可以提出:

struct Operation {
    bool updateNeeded{false};
    unsigned int opcode{};
    unsigned long operand1{};
    unsigned long operand2{};
    unsigned long operand3{};
    size_t indexOfRelated{};
};

std::vector<Operation> operation;
struct操作{
bool updateNeeded{false};
无符号整数操作码{};
无符号长操作数1{};
无符号长操作数2{};
无符号长操作数3{};
尺寸指数化{};
};
std::向量运算;
当然,您可以根据需要添加更多属性

然后您可以读取源数据并填写
std::vector
。在阅读完完整的源代码后,您将再次检查数据,并修复未解决的问题


然后,将其交给虚拟机,或发出最终指令。

您正在模拟汇编语言?对于一个非常简单的解决方案,您始终可以发出近跳转,除非用户指定“short”关键字来覆盖。您还可以在跳转之前检测目标跳转,并自动将其缩短。