处理器 8086 汇编规则和限制

Processor 8086 assembly rules and limitations

我有一些关于 8086 汇编语言编码的问题。

  1. 你能对每个算术和逻辑运算(加、减、移位运算......)使用所有通用目的吗

  2. 你能把常量赋给寄存器吗(mov ax, 1; mov bx, 5...)

  3. 你能以所有可能的组合将一个寄存器分配给另一个寄存器吗(mov ax, ss; mov es, bp; mov bp, cx; mov si, di...)

如果任何问题的答案是否定的,有什么限制?

  • 一些说明适用于某些寄存器作为@Wayne Conrad 说。例如 div 指令 (div arg) 仅使用 AX 或 DX:AX dividend,AH 或 DX 存储余数,AL 或 AX 存储商。 (用于存储 dividend、余数和商的寄存器因 div异或尺寸)

    DIV CX divides DX:AX 由CX对,余数存入DX和商 在 AX.

  • 是的,您可以将寄存器、内存值或立即值移动到 一个寄存器 只要它的操作码已经实现 .
  • 没有。除非实施相应的移动指令操作码,否则你不能。为了 例如 mov sreg,sreg 未实现(你可以在 coder32 中查看 instruction reference), 所以你不能做 "mov es, fs" 除非有 mov sreg, sreg 操作码实现。还有一些寄存器 不能像 CS 和 那样直接访问(感谢@fuz 的指点 那) IP 由于安全 "restrictions".

简单地说,"limitations" 是操作码。

如果我们谈论通用寄存器(axbxcxdxbpspsidi),以及它们的 "narrow" 8 位对应物(也就是英特尔文档中的 r16r8):

  1. 正则算术和逻辑运算(add,sub,shl/shr,sal/sar, rol/ror, and, or, ...) 允许通用 r/m8r/m16 作为第一个操作数。

    至于第二个操作数,它取决于具体的指令——算术和逻辑指令允许 r8/r16(并且 al/[=10 有更短的形式=]作为目标寄存器),而shifts/rotates只允许cl(加上立即数,固定1,...)。

    一些 "complex" 算术指令,例如除法和乘法,硬连接到使用特定的寄存器。

  2. 是的,movmov r8,imm8mov r16,imm16 形式。

  3. 是的,movmov r/m8,r8mov r/m16,r16 形式。


然后是段寄存器(csdsesss,也就是英特尔操作码文档中的 Sreg

  1. 常规算术和逻辑运算没有编码可用于 Sreg
  2. 不,没有mov Sreg,imm16这样的东西;您必须首先通过通用寄存器(或通过堆栈 - 每个代码高尔夫球手都知道 push imm16/pop Sregmov r16,imm16/mov Sreg,r16 短)。
  3. 差不多; movmov Sreg,r/m16mov r/m16,Sreg 形式,但没有 mov Sreg,Sreg 形式。

至于其他的寄存器(FLAGS、IP、x87 FPU栈,...)它们完全是独立的,一般只能通过专用指令访问。

1) Can you use all general purpose for every arithmetic and logical operation (add, sub, shift operations...)

几乎可以,但有一些例外。
例外是具有隐式操作数的指令。例如:div、cl 移位、字符串指令等

2) Can you assign constant to registers (mov ax, 1; mov bx, 5...)

是的,适用于所有 GP 寄存器。
像段寄存器这样的特殊用途寄存器只能通过 GP 寄存器分配。

3) Can you assign one register to another in all possible combinations (mov ax, ss; mov es, bp; mov bp, cx; mov si, di...)

是的,但有一些明显的例外。
您不能在两个非 GP 寄存器之间执行 mov

详情见:http://www.felixcloutier.com/x86/MOV.html