首页 > 解决方案 > MIPS中括号的作用是什么?

问题描述

我一直在研究一本项目书作为 MIPS 的介绍,但遇到了一个问题。书中的代码行之一是lb $t3, ($t2). 我不知道括号是做什么的,因为在此之前,我没有看到它们被使用过,而且这本书只是一开始就没有提到它们。为什么代码不只是lb $t3, $t2

标签: assemblymipsaddressing-mode

解决方案


MIPS 寻址模式语法是constant($reg).

($t2)允许作为 . 的特殊情况简写0($t2)。相同的指令可以
lb $t3, 13($t2)将地址从内存中的字节加载(和符号扩展)13 + $t2到寄存器$t3中。

MIPS 唯一的寻址模式是reg + sign_extended_imm16; 加载/存储指令(包括lblbu)是 I 型的。省略0in0($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, $t2lb $t3, 0($t2). 但是 asm 语法是由汇编器(的作者)定义的,而 MIPS 语法的设计者决定不这样做。


在此之前,我还没有看到它们被使用过,而且这本书只是一开始就没有提到它们。

继续阅读; 希望本书在首次介绍新语法后的一段时间内继续解释它。教程或书籍向您展示一些代码作为示例而不停止解释所有内容是完全正常的,尤其是当解释基于尚未涉及的概念时。


推荐阅读