assembly - MIPS指令解码
问题描述
我试图了解如何解码 MIPS 二进制指令。
我使用 gcc 在 Debian MIPS 系统上用 C 语言编译了一个 hello world 程序,objdump 显示 .text 部分中的第一条指令是:
600: 03e00025 move zero,ra
我不明白它如何确定这是MOVE
指令。
03e00025
是00000011111000000000000000100101
二进制的。如果我理解正确,这里的前 6 位是操作码,在这种情况下全为 0,这意味着它是 R 型指令,所以我们必须查看最后 6 位,即100101
. 查看MIPS 指令集手册,它看起来应该是OR
指令。MOVE
我什至在那个手册里都找不到。
对此进行谷歌搜索,我发现程序集中显然有“伪”指令,并且应该move $t, $s
扩展为addiu $t, $s, 0
,但如果我查看手册ADDIU
有 opcode 001001
。我发现的另一个结果声称它转换为ADD
但最后六位ADD
应该是100000
,所以这也不适合。
我错过了什么?
解决方案
MIPS 机器代码没有针对 的特定操作码move
,但为了方便人类,许多汇编程序支持伪指令,如li
、la
和move
,它们可以组装成一条或多条真实机器指令。 addiu
是一个常见的。
objdump 将指令解码为or $0, $ra, $0
(根据 Jester)向您展示它的实际编码方式是完全正确的。
move
出于某些目的,反汇编程序对任何常用的将寄存器复制到助记符的方法进行解码都是有意义的。从读取寄存器中添加或 ORing 立即0
数或零$zero
,对值不做任何事情,因此它被原封不动地复制。
阅读 asm 时,您通常不在乎它是or
, ori
,addiu $0, $ra, 0
还是其他。
不同的汇编器可能对伪指令使用不同的实现move
,或者手写 asm 可以使用其中的任何一个。我认为这两种方式都不会对性能产生任何影响。因此,使用哪条机器指令来实现 a 的细节move
取决于汇编器。
我不确定move
带有目的地的 a 的意义$zero
是什么。那将是无操作的,因为$zero
丢弃了写入。(它相当于 的 CPU 寄存器/dev/zero
)
推荐阅读
- java - Java 转 ASN1 可读字符串
- php - 在 laravel 中下载之前显示或预览 pdf 文件
- python - 在发布期间/之前清理 Git 历史记录、添加新提交并将更改带回开发人员的推荐方法
- c++ - 如何从圆上的中间点和其他点之间的角度计算圆上的点
- java - Git - 在不同的行上创建一个带有键值对和符号的 JSON 文本文件,以确保没有合并问题
- python - 将行转换为熊猫列下的值列表
- cassandra - 尝试在 cqlsh 中运行创建和选择时出错:NoHostAvailable
- php - builder where 和 codeigniter query builder 工作方式的区别
- java - 运行 jar 文件时无法找到或加载主类
- django - 如何在 Django 中将日历范围设置为 1 周