我试图编写一个小的8086+汇编程序,可能只是真正的模式,并且可以解决大部分可能的指令。
x86指令很复杂,需要复杂的表解决方案,这很好,但我想要更小/更简单的东西。
我的一个想法是从操作码开始,并制作一组替代的助记符/寻址模式/寄存器,它们与实际的机器指令更紧密相关。
这已经完成了,我在哪里可以阅读它?我的直觉是说这一定已经完成了,但我无法在网上找到任何东西。
我已经研究过的事情:
AT& T语法:没有解决问题,你还需要一个复杂的 表查找;最后它与英特尔语法基本相同。
CRASM512.ASM:一个很酷的512字节技巧汇编程序。非常令人印象深刻但是 不可用(并不意味着)。语法仍然基于 英特尔也是如此。
仅使用"同质编码的子集"说明。这是 我目前正在尝试什么,并使用更小,更简单的表 驱动方法比完全成熟的x86汇编程序。
问题是我仍然需要检查无效指令,x86足够复杂,我只能使表驱动方法成为 有点简单,不简单。所以这是90%的复杂性 结果的10%,因为与实际交易相比,主要是表格发生了变化。
答案 0 :(得分:4)
y86是一个非常简化的架构(for teaching purposes),但实现了您的一个想法:而不是拥有根本不同的事物的多种不同形式的Leaf | Node
,对于它支持的三种不同的mov
类操作码,它有不同的助记符:
mov
:立即 - > REG irmovl V, %rB
:reg - >记忆(商店)rmmovl %rA, D(%rB)
:记忆 - > reg(加载)这是y86的AT& T语法风格,目的地是第二名。 AT& T语法使用mrmovl D(%rB), %rA
和%
装饰来避免reg名称和符号之间的混淆。 IDK,如果它使解析器更小或更大。
将此想法应用于x86,您可以对同一指令的不同形式使用不同的助记符。
如果您更关心易于解析而不是人类可读性和与现有asm语法的相似性,那么您总是可以按照mod / rm字节中的编码顺序列出操作数。 e.g。
$
注意最后两行:第一个操作数总是" r"在mod / rm字节中,而不是目标。它是指令编码的文本表示,而不是人类可用的语法。我认为这是你想要的那种想法吗?
根据您希望汇编程序的智能程度,您可以选择imm8和imm16形式的即时指令。对于disp8,disp16或无位移内存编码,可能更容易要求0而不是空条目。
通常每个人都想要一个为您选择最佳编码的智能汇编程序(例如,使用不使用mod / rm字节的EAX特定操作码)。 ESP。对于x86-64,在不需要时避免使用REX前缀,或者将addbir al, 5 ; b = byte, i = immediate, r = register. opcode 80 /0 with al encoded in the mod/rm byte, imm8
addbia al, 5 ; a = ax/al: opcode 04 imm8
; w=word, m=memory
addwrm cx, 0, bx, ; add cx, [0 + bx + (no index)] encoding: 03 mod/rm
addwmr cx, 0, , si ; add [0 + (no base) + si], cx encoding: 01 mod/rm
优化为mov rax, 0x1234
,这很不错。
对于负载与mov-immediate使用不同的助记符肯定会有价值,因为它是common source of confusion for asm beginners。 (特别是因为MASM和NASM语法因mov eax, 0x1234
的含义而异)。