assembly - MIPS中括号的作用是什么?
问题描述
我一直在研究一本项目书作为 MIPS 的介绍,但遇到了一个问题。书中的代码行之一是lb $t3, ($t2)
. 我不知道括号是做什么的,因为在此之前,我没有看到它们被使用过,而且这本书只是一开始就没有提到它们。为什么代码不只是lb $t3, $t2
?
解决方案
MIPS 寻址模式语法是constant($reg)
.
($t2)
允许作为 . 的特殊情况简写0($t2)
。相同的指令可以
lb $t3, 13($t2)
将地址从内存中的字节加载(和符号扩展)13 + $t2
到寄存器$t3
中。
MIPS 唯一的寻址模式是reg + sign_extended_imm16
; 加载/存储指令(包括lb
和lbu
)是 I 型的。省略0
in0($t2)
只是源代码级别的语法细节;机器代码仍然有 16 个零位来编码该常数零。
顺便说一句,我忽略了 MIPS 的索引 FP 加载/存储指令的存在,比如lwxc1
使用 2 个整数寄存器。它们只是 FP,可能是因为整数存储版本需要 3 个 GP 寄存器作为输入,但该寄存器文件否则只需要 2 个读取端口(用于标量管道)。(架构师显然认为加载和存储之间的对称性比只为加载提供 2 寄存器寻址模式更重要;这对于很多代码来说都很好并且有用)。
在一些较新的 MIPS 版本中也lwpc
有 PC 相关寻址。但是lw
// lb
_lbu
等等没有位来编码什么类型的寻址模式;它总是 reg + imm16。其他任何事情都需要不同的指令,而经典 MIPS 没有其他任何东西。
语义(对于 asm 文本语法的人类读者而言)是取消引用操作,就像在 C 中一样,int t3 = *t2;
或者t2[0]
加载指向的值 ( lb
) 而不是int tmp = (int)p
将指针复制为整数 ( move
)。
()
始终是内存操作数,只能与加载或存储指令一起使用。裸寄存器不是内存寻址模式,不能用作第二个操作数来加载或存储指令。
加载/存储指令在寻址模式上需要括号是一件好事,因此您不会混淆哪个操作数是地址,哪个是值。例如sw $t3, 12($t2)
,将字 in$t3
存储到地址处的内存字中12+$t2
。如果sw $t3, $t2
是有效的语法,您可能会忘记地址总是在 MIPS 上的内存指令的右侧(就像大多数 RISC 一样),即使每个其他指令都将目标作为第一个操作数。
这使它在视觉上与move $t3, $t2
. 在代码块中发现加载和存储很高兴能够直观地完成。
如果您正在为 MIPS 汇编语言设计自己的语法,或编写汇编程序,则可以lb $t3, $t2
将lb $t3, 0($t2)
. 但是 asm 语法是由汇编器(的作者)定义的,而 MIPS 语法的设计者决定不这样做。
在此之前,我还没有看到它们被使用过,而且这本书只是一开始就没有提到它们。
继续阅读; 希望本书在首次介绍新语法后的一段时间内继续解释它。教程或书籍向您展示一些代码作为示例而不停止解释所有内容是完全正常的,尤其是当解释基于尚未涉及的概念时。
推荐阅读
- java - 登录 Google play 游戏时是否可以不显示 Google play 游戏徽标
- sql - 如何从sql oracle 9i中的字符串中提取日期
- vue.js - 如何在 Vue.js (2.0) 中优先考虑指令
- python - 如何在凌乱的植物图像上获得正确的轮廓?
- jquery - 嵌入式 jquery 脚本不与 html 一起执行
- angular - 如何在不订阅每个输入/组件角度变化的情况下更新数据变化的摘要状态?
- postgresql - Postgresql 获取聚合变量的第一个 True 值
- amazon-web-services - 如何在 AWS(手动创建)中使用 Terraform 资源?
- ios - 在注册 Apple 企业帐户之前,我是否需要从商店中删除我的应用程序
- javascript - 如何在按钮单击时使项目有机会掉落