如何解决标签大小不固定时如何处理前向引用
我正在尝试用 C++ 编写 8086 模拟器。 但是我遇到了问题。
假设代码是:
MOV AL,BL
JMP X
MOV BL,CL
MOV DL,CL
.
.
.
X:
ADD AX,BX
HLT
现在JMP X的机器码将取决于X,无论是near location or short location
near: 8Bit 地址[00-ff]
短: 16Bit 地址(ff-ffff]
因此,如果 JMP 指令的大小曾经是恒定的(固定大小),那么我可以进一步移动,每当我找到 X 时,我都可以将其地址放回原处。 但是这里我不能再移动了,因为下一个位置也取决于 JMP X 并且其大小不固定。
我不知道如何处理它。
解决方法
您可能对 jmp
有更多问题。请参阅以下可能的操作码及其含义:
EB cb JMP rel8 Jump short,relative,displacement relative to next instruction.
E9 cw JMP rel16 Jump near,displacement relative to next instruction.
E9 cd JMP rel32 Jump near,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,address given in r/m32.
EA cd JMP ptr16:16 Jump far,absolute,address given in operand.
EA cp JMP ptr16:32 Jump far,address given in operand.
FF /5 JMP m16:16 Jump far,address given in m16:16.
FF /5 JMP m16:32 Jump far,address given in m16:32.
因此,您需要考虑更多特殊情况。
解决方案是实现多通道汇编器。无论如何,您都需要将所有操作码和操作数存储在 std::vector
或任何地方。然后就可以在第2步设置正确的数据了。
如果您为操作码和操作数定义一个 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;
当然您可以根据需要添加更多属性。
然后就可以读取源数据并填充std::vector
。阅读完整的源代码后,您将再次查看数据,并修复未解决的问题。
然后,将其交给虚拟机,或发出最终指令。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。