微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

标签大小不固定时如何处理前向引用

如何解决标签大小不固定时如何处理前向引用

我正在尝试用 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 举报,一经查实,本站将立刻删除。