Assembly 处理器8086汇编规则和限制

Assembly 处理器8086汇编规则和限制,assembly,x86-16,cpu-registers,Assembly,X86 16,Cpu Registers,我有一些关于8086汇编语言编码的问题 你能为每一个算术和逻辑运算(加法、减法、移位运算…)使用所有的通用功能吗 你们能给寄存器分配常数吗(mov ax,1;mov bx,5…) 您能否以所有可能的组合(mov ax、ss、mov es、bp、mov bp、cx、mov si、di…)将一个寄存器分配给另一个寄存器 如果任何问题的答案都是否定的,那么限制是什么? 某些说明适用于某些寄存器@Wayne Conrad 说。例如,div指令(div arg)仅将AX或DX:AX用于 股息、AH或DX用

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

  • 你能为每一个算术和逻辑运算(加法、减法、移位运算…)使用所有的通用功能吗

  • 你们能给寄存器分配常数吗(mov ax,1;mov bx,5…)

  • 您能否以所有可能的组合(mov ax、ss、mov es、bp、mov bp、cx、mov si、di…)将一个寄存器分配给另一个寄存器

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

    • 某些说明适用于某些寄存器@Wayne Conrad 说。例如,div指令(div arg)仅将AX或DX:AX用于 股息、AH或DX用于存储余数,AL或AX用于存储商。 (用于存储股息、余数和商的寄存器因 除数大小)

      DIV CX将DX:AX对除以CX,剩余部分存储在DX和商中 在斧头上

    • 是的,您可以将寄存器、内存值或立即值移动到 寄存器,只要其操作码已实现
    • 不可以。除非实现了相应的移动指令操作码,否则不能。对于 示例mov-sreg,sreg没有实现(),所以除非您已经实现,否则不能执行“mov-es,fs” mov sreg,sreg操作码已实现。还有一些寄存器 无法像CS和(由于@fuz的指向)那样直接访问 这是由于安全“限制”造成的

    简单地说,“限制”是操作码。

    如果我们谈论通用寄存器(
    ax
    bx
    cx
    dx
    bp
    sp
    si
    di
    ),以及它们的“窄”8位对应项(即英特尔文档中的
    r16
    r8
    ):

  • 常规算术和逻辑运算(
    add
    sub
    shl
    /
    shr
    sal
    /
    sar
    rol
    ror,
    ,…)允许通用的
    r/m8
    r/m16
    作为第一个操作数

    至于第二个操作数,它取决于特定的指令-算术和逻辑指令允许一个
    r8
    /
    r16
    (并且将
    al
    /
    ax
    作为目标寄存器具有较短的形式),而移位/旋转只允许
    cl
    (加上立即数,固定1,…)

    一些“复杂”的算术指令,如除法和乘法,是硬连线的,以使用特定的寄存器

  • 是,
    mov
    具有
    mov r8、imm8
    mov r16、imm16
    表单

  • 是的,
    mov
    具有
    movr/m8、r8
    movr/m16、r16
    格式


  • 然后是段寄存器(
    cs
    ds
    es
    ss
    ,也称为英特尔操作码文档中的
    Sreg
    ):

  • 常规算术和逻辑运算没有可在
    Sreg
    上操作的编码
  • 不,没有“mov Sreg,imm16”这样的东西;您必须首先通过一个通用寄存器(或通过堆栈-每个代码高尔夫球手都知道
    push imm16
    /
    pop Sreg
    mov r16、imm16
    /
    mov Sreg、r16
    短)
  • 几乎
    mov
    mov Sreg,r/m16
    mov r/m16,Sreg
    表单,但没有
    mov Sreg,Sreg
    表单

  • 至于其他寄存器(标志、IP、x87 FPU堆栈等),它们完全独立,通常只能通过专用指令访问

    1) 你能为每一个算术和逻辑运算(加法、减法、移位运算…)使用所有的通用功能吗

    几乎是的,只有少数例外。
    例外情况是具有隐式操作数的指令。e、 g.:
    div
    、按cl移位、字符串指令等

    2) 你们能给寄存器分配常数吗(mov ax,1;mov bx,5…)

    对所有GP寄存器都是。
    特殊用途寄存器(如段寄存器)只能通过GP寄存器分配

    3) 您能否以所有可能的组合(mov ax、ss、mov es、bp、mov bp、cx、mov si、di…)将一个寄存器分配给另一个寄存器

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


    有关详细信息,请参阅:

    对于(2),您不能将直接数据移动到段寄存器或浮点寄存器中。对于(3),在8086上可以将数据移动到cs寄存器,从而导致跳远。你甚至可以打开电脑。在以后的体系结构修订版中,这两项都是禁止的。“所以你不能做
    mov-es,fs
    ”。这不是最好的例子,因为8086上不存在
    FS
    段寄存器。最好写
    mov es,ds
    作为一个例子……你有没有试过阅读手册或文档?现在我想知道是谁投票删除了这个问题。我们可能会争论它是否太宽泛,但删除一个有三个经过充分研究的答案的问题只会是对其他人工作的一个混蛋。LDS和LES指令将32位常量加载到一对寄存器中,其中一个是段寄存器DS或ES。