在汇编语言中,在8085微处理器的指令集下,假设我们有以下操作ADD B
。
我知道这意味着"将B的寄存器数据添加到累加器寄存器中,并将内容保存回累加器"。
-
这里什么是助记符,什么是操作码。
-
ADD
(只有 ADD 而不是ADD B
)是操作码还是助记符? - 内部助记符转换为十六进制代码,例如 3E,那么这里是什么这个十六进制代码是指、
ADD
还是ADD B
。
请帮忙。
通常操作码是指操作的类型(ADD),寄存器B是一个操作数。但是,对于固定且数量较少的操作数,对于所有可能的操作数,同一操作可以具有不同的操作码。
操作码是指标识指令的二进制序列。 所以对于 8085,我相信0x80将是"ADD B"的操作码
助记符是人类可读的名称,可帮助您记住说明。 因此,字符串"ADD B"是0x80的助记符。 "ADD B"比0x80容易记住。
某些体系结构具有相同助记符的许多不同形式。 在查看此类体系结构的示例时,事情应该更容易理解。
例如,x86 有 5 种形式的 32 位添加。 (8 位添加的形式也一样多,当然除了没有 32 位即时版本。 16 位和 64 位加法在 32 位编码前面使用前缀字节进行编码。
表格格式:操作码和操作数编码/助记符/操作数(目标,src)
05 id ADD EAX, imm32 # special-case save-one-bye for adding to the accumulator
81 /0 id ADD r/m32, imm32
83 /0 ib ADD r/m32, imm8
03 /r ADD r32, r/m32 # src can be memory
01 /r ADD r/m32, r32 # dest can be memory
所以对于add eax, edx
,有两种可能的编码:01 D0
(由GNU选择)或03 whatever
(以其他顺序查找操作数的mod/rm字节的编码留给读者练习。
/0
意味着mod/rm字节中未使用的src-reg位被借用为操作码的一部分。 83 /4 ib
AND r/m32, imm8
. 当人们说 x86 机器码很难解码时,这就是他们正在谈论的事情(除了可变长度的性质,以及可选的前缀字节意味着操作码甚至不是第一个字节的事实...... 您必须主要解码一条指令,然后才能知道开始解码下一条指令需要多长时间。 x86 指令的并行 4 宽解码耗电是有原因的。
更极端的情况是 x86 将 mov
用于几种不同类型的指令,由操作数确定:
- 常规
mov r32, r/m32
(或相反) - 立即移动以寄存器或内存
- 移步机到/传出段寄存器(所有这三种形式都记录在手册的同一页上)
- MOV与/从控制寄存器移动(甚至在手册中有不同的条目)
- MOV与调试寄存器之间的移动(手册中的另一个单独条目)。
我想不出两个不同的助记符产生相同操作码的情况。 但是单个助记符可以生成具有不同操作数的不同操作码。
操作数甚至可以编码到操作码字节中,用于非常常用的指令,以节省空间(这是谢尔盖的答案)。 你可以把x86的B8
操作码想象成mov-imm32-to-eax。 (BF
操作码的B8
都是立即注册的,每个操作码都有不同的目标注册。 32 位 x86 具有用于寄存器的 inc/dec 的单字节操作码。 x86-64 重新利用了 16 个操作码的连续范围,用作 REX 前缀字节(将双字节inc r/m32
形式作为inc eax
的唯一选项。