标签大小不固定时如何处理正向引用 我试图在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”关键字来覆盖。您还可以在跳转之前检测目标跳转,并自动将其缩短。