我对8086汇编语言的编码有一些疑问。
您是否可以将所有通用目的用于每个算术和逻辑运算(添加,子,班次操作......)
可以为寄存器分配常量(mov ax,1; mov bx,5 ...)
你能否以一切可能的组合为一个寄存器分配一个寄存器(mov ax,ss; mov es,bp; mov bp,cx; mov si,di ...)
如果任何问题的答案都是否定的,那么有哪些限制?
答案 0 :(得分:4)
如果我们谈论通用寄存器(ax
,bx
,cx
,dx
,bp
,sp
,{{1 },si
),以及他们的“窄”8位对应项(英特尔文档中的AKA,di
和r16
):
常规算术和逻辑运算(r8
,add
,sub
/ shl
,shr
/ sal
,{{ 1}} / sar
,rol
,ror
,...)允许通用and
或or
作为第一个操作数。
对于第二个操作数,它取决于特定指令 - 算术和逻辑指令允许r/m8
/ r/m16
(并且r8
/ r16
的表格更短作为目标寄存器),而shift / rotate只允许al
(加上immediates,固定1,......)。
一些“复杂”算术指令,例如除法和乘法,是硬连线使用特定的寄存器。
是的,ax
包含cl
和mov
表单。
是的,mov r8,imm8
包含mov r16,imm16
和mov
表单。
然后,在英特尔操作码文档中有段寄存器(mov r/m8,r8
,mov r/m16,r16
,cs
,ds
,AKA es
:
ss
进行操作的编码。Sreg
这样的东西;你必须首先通过通用注册(或通过堆栈 - 每个代码高尔夫球手都知道Sreg
/ mov Sreg,imm16
比push imm16
/ pop Sreg
更短。 mov r16,imm16
有mov Sreg,r16
和mov
表单,但没有mov Sreg,r/m16
表单。至于其他寄存器(FLAGS,IP,x87 FPU堆栈......),它们完全独立,通常只能通过专用指令访问。
答案 1 :(得分:0)
某些说明适用于某些注册表@Wayne Conrad 说过。例如,div指令(div arg)仅使用AX或DX:AX 红利,AH或DX存储余数,AL或AX存储商。 (用于存储股息,余额和商的寄存器因人而异 除数大小)
DIV CX通过CX划分DX:AX对,将剩余部分存储在DX和商中 在AX。
简单来说,“限制”是操作码。
答案 2 :(得分:0)
1)您是否可以将所有通用目的用于每个算术和逻辑运算(添加,子,移位操作......)
非常好,除了少数例外。
例外是具有隐式操作数的指令。例如: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
。
有关详细信息,请参阅:http://www.felixcloutier.com/x86/MOV.html