处理器 8086 汇编规则和限制
Processor 8086 assembly rules and limitations
我有一些关于 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
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" 是操作码。
如果我们谈论通用寄存器(ax
、bx
、cx
、dx
、bp
、sp
、si
、di
),以及它们的 "narrow" 8 位对应物(也就是英特尔文档中的 r16
和 r8
):
正则算术和逻辑运算(add
,sub
,shl
/shr
,sal
/sar
, rol
/ror
, and
, or
, ...) 允许通用 r/m8
或 r/m16
作为第一个操作数。
至于第二个操作数,它取决于具体的指令——算术和逻辑指令允许 r8
/r16
(并且 al
/[=10 有更短的形式=]作为目标寄存器),而shifts/rotates只允许cl
(加上立即数,固定1,...)。
一些 "complex" 算术指令,例如除法和乘法,硬连接到使用特定的寄存器。
是的,mov
有 mov r8,imm8
和 mov r16,imm16
形式。
是的,mov
有 mov r/m8,r8
和 mov r/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
形式。
至于其他的寄存器(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
。
我有一些关于 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 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" 是操作码。
如果我们谈论通用寄存器(ax
、bx
、cx
、dx
、bp
、sp
、si
、di
),以及它们的 "narrow" 8 位对应物(也就是英特尔文档中的 r16
和 r8
):
正则算术和逻辑运算(
add
,sub
,shl
/shr
,sal
/sar
,rol
/ror
,and
,or
, ...) 允许通用r/m8
或r/m16
作为第一个操作数。至于第二个操作数,它取决于具体的指令——算术和逻辑指令允许
r8
/r16
(并且al
/[=10 有更短的形式=]作为目标寄存器),而shifts/rotates只允许cl
(加上立即数,固定1,...)。一些 "complex" 算术指令,例如除法和乘法,硬连接到使用特定的寄存器。
是的,
mov
有mov r8,imm8
和mov r16,imm16
形式。是的,
mov
有mov r/m8,r8
和mov r/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
形式。
至于其他的寄存器(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
。