MIPS 中基于指针的数组访问

2023-12-25

MIPS 中基于指针的数组访问是什么意思?


“基于指针的数组访问”还有一个额外的可能含义或含义:

您可能有一个指向数组的指针,而不是位于固定地址的数组。实际上,在 C/C++ 中,“指向数组的指针”实际上通常只是指向数组第一个元素的指针。基本上,您有一个作为函数参数的数组,或者一个指向作为结构或类成员的数组的指针:

 void Foo(char a[]); 
   /*or*/ void Foo(char *a);
 struct Bar {  int offset4bytes; char* a; };

通常,当您要使用这样的数组时,数组的基地址将被加载到寄存器中。

现在假设您要访问这样一个数组的元素 i,

 char tmp = a[i];

假设 r1 包含数组地址。 (实际上,可能是由调用约定指定的不同寄存器用于函数参数。编译器发现可用于其他代码的任何内容。)

假设 i 位于寄存器 r2 中。

并且,为了更好地衡量,让 tmp 为 r3。

在某些指令集上,例如Intel x86,有一种寻址模式,看起来像

  MOV r3, (r2,r1)4

即寻址模式可以添加两个寄存器和一个偏移量(我在结构示例中任意添加了一个字段,以便我可以展示这一点)。

哎呀,他们甚至可以缩放其中一个寄存器,即所谓的索引寄存器:

  MOV r3, (r2*2,r1)4

或者我更喜欢这样写

  r3 := load( Memory[r2<<1+r1+4]

然而,MIPS 没有这种基址+_index*scale+offset 寻址模式。大多数MIPS内存访问指令仅限于寄存器+偏移量。因此,对于 MIPS,您可能必须这样做

  ADDU r10, r1,r1    ; dest on left. r10 = 2*r1
  ADDU r11, r2,r10  
  LB r3,(r11)4

也就是说,您可能需要添加额外的 RISC 指令来完成 x86 在具有复杂寻址模式的一条 CISC 指令中所做的事情。然而,这种寻址并不常见,并且通常可以避免。


此外,即使只是在固定地址寻址数组也可能需要 MIPS 中的额外指令。 x86 指令可以有 32 位内存偏移量 - 在这种情况下实际上可能是数组的绝对地址。 MIPS 指令仅限于 16 位偏移量 - MIPS 指令是固定宽度的,即 32 位宽。因此,甚至可能需要单独的指令来访问固定地址处的数组,通常是将地址的高位加载到寄存器中。

还有更多 - MIPS 有更新的指令,如 LUXC1,具有 reg+reg 寻址模式。但没有缩放索引,也没有第三个偏移分量。


由于这种受限的寻址模式,天真的编译器为循环生成的代码如下

   for(int i=0;i<N;i++) {
      this->a[i] = 0;
   }

如果循环包含上述多指令序列,效率会很低。

一个循环,例如

   for(char *p=this->a;p<&(this->a[N]);p++) {
      *p=0;
   }

或者,等价地

   for(char *p=this->a;p<this->a+N;p++) {
      *p;
   }

甚至有时

   for(i=-N,*p=this->a;i<0;i++,p++) {
      *p=0;
   }

可能会更有效,因为,例如在前两个中,只有一条指令来执行存储。 (如果遍历多个数组,最后一个通常才是胜利。

现在,在一个简单的示例中,任何好的编译器都会为您执行此优化。但有时编译器更喜欢这种基于指针的访问。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MIPS 中基于指针的数组访问 的相关文章

  • 寄存器寻址模式与直接寻址模式

    我在试卷中遇到过这个问题 它指出 哪种给定的寻址模式更快 为什么 寄存器寻址方式 直接寻址方式 现在根据我的说法 寄存器寻址模式应该更快 因为寄存器是计算机中最快的存储位置 这是正确答案吗 请帮忙 谢谢 两种寻址模式之间的区别是 地址的来源
  • 使用 (float&)int 进行类型双关可以正常工作,(float const&)int 会像 (float)int 一样转换吗?

    VS2019 发布 x86 template
  • “mov (%ebx,%eax,4),%eax”如何工作? [复制]

    这个问题在这里已经有答案了 一直在从事装配作业 并且在很大程度上我对装配非常了解 或者至少对于这项任务来说足够好 但这个 mov 的声明让我很困惑 如果有人能解释这个 mov 语句如何操作寄存器值 我将非常感激 mov ebx eax 4
  • 为什么如果内存组织为字,则程序计数器加 1;如果内存组织为字节,则程序计数器加 2?

    如果在计算机中一条指令是 16 位 并且如果存储器被组织为 16 位字 则通过在当前指令的地址中加 1 来计算下一条指令的地址 如果内存是按字节组织的 可以单独寻址 那么我们需要在当前指令地址上加二 得到顺序执行的下一条指令的地址 为什么会
  • 阴影空间示例

    EDIT 我接受了下面的答案 并添加了我自己的代码的最终修订版 希望它向人们展示影子空间分配的实际示例 而不是更多的文字 编辑 2 我还设法在 YouTube 视频 所有内容 的注释中找到了一个调用约定 PDF 的链接 其中有一些关于 Li
  • 带有适用于 MS-Windows 的工具链的预构建 MIPS 交叉编译器

    我在我的 Linux 机器上使用 MIPS 交叉编译器 效果很好 现在我需要在 Windows 上编译相同的应用程序 我正在网上搜索一些适用于 MS Windows 的预构建 MIPS 交叉编译器 带有工具链 但没有成功 由于我不确定该怎么
  • 如何在 icarus verilog 中包含文件?

    我知道基本的 include filename v 命令 但是 我试图包含另一个文件夹中的模块 现在 该模块还包括同一文件夹中存在的其他模块 但是 当我尝试在最顶层运行该模块时 出现错误 C Users Dell Desktop MIPS
  • MikeOS 引导加载程序中的堆栈段

    我不明白这段代码 mov ax 07C0h Set up 4K of stack space above buffer add ax 544 8k buffer 512 paragraphs 32 paragraphs loader cli
  • 设置 IRQ 映射

    我正在遵循一些教程和参考文献来尝试设置我的内核 我在教程中遇到了一些不熟悉的代码 但根本没有解释它 这是我被告知映射的代码16 IRQs 0 15 到 ISR 地点32 47 void irq remap void outportb 0x2
  • X86 预取优化:“计算 goto”线程代码

    我有一个相当重要的问题 我的计算图有循环和多个 计算路径 我没有制作一个调度程序循环 其中每个顶点将被一一调用 而是将所有预先分配的 框架对象 放置在堆中 代码 数据 这有点类似于线程代码 甚至更好 CPS 只是在堆中跳转 执行代码 每个代
  • 这种没有推送寄存器的交换有多安全?

    我对汇编非常陌生 下面的代码应该通过两个不同的函数交换两个整数 首先使用swap c然后使用swap asm 但我怀疑 我是否需要push 我的意思是保存 汇编代码之前寄存器的每个值和pop稍后 就在返回之前 main 换句话说 如果我返回
  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • 如何使用 Bochs 运行汇编代码?

    我想使用 Bochs 作为 8086 模拟器 是否有捷径可寻 我想要的是类似 emu8086 的东西 http www emu8086 com http www emu8086 com 如果程序的初始部分适合 512 字节 并且您不介意将自
  • 错误 LNK2019:函数 main 中引用的外部符号无法解析

    我正在尝试在 C 中运行我的简单汇编代码 我只有两个文件 cpp 文件和 asm 文件 编译时出现错误 见下文 如果有人可以提供帮助 我将不胜感激 这是我的 main cpp 文件 include
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 添加冗余赋值可以在未经优化的情况下编译时加快代码速度

    我发现一个有趣的现象 include
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • 何时可以重用avx指令中的源寄存器

    在 avx 指令中用作源的寄存器何时可以在指令开始处理后重用 例如 我想使用vgatherdps该指令消耗两个 ymm 寄存器 其中之一是位移索引 我意识到vgatherdps由于数据的局部性较差 因此需要花费大量时间来收集 位移索引寄存器
  • 汇编器8086将32位数字除以16位数字

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw
  • CISC 机器 - 它们不只是将复杂指令转换为 RISC 吗?

    也许我在架构上存在误解 但如果机器有 比如说 乘法指令 该指令是否未转换为更小的指令 或者过于复杂以至于最终与等效的 RISC 指令具有相同的速度 乘法是一个不好的例子 它在两种体系结构中都是一条指令 将上面的 乘法 替换为 CISC 中更

随机推荐

  • 如何运行将数据加载到其他项目 BigQuery Table 的云编辑器任务

    我在项目 A 下创建了云编辑器环境 我想将数据加载到其他项目 B BigQuery 表中 我知道任务 GCSToBigQueryOperator 但它没有成功 它失败了 我想知道如何实现这一点 我想从项目 A 运行一个将数据加载到项目 B
  • 滚动到 angular2 时动画进入视图

    我找到了一个库 用于在滚动到 aos https github com michalsnik aos 但它似乎没有任何 angular2 绑定可供使用 有谁知道如何在 Angular2 中完成类似的事情 或者至少配置 aos 在 Angul
  • 如何在iPhone中创建应用程序包?

    我使用 XCode 制作了一个小型应用程序 我如何创建一个应用程序包以将其安装在 iPhone 中 谁能帮我解决这个问题 提前致谢 是的 如上所述 您需要支付 99 美元的开发者费用 完成此操作后 您可以通过 XCode 直接部署到使用配置
  • PHP 中的数组打乱顺序

    我有以下代码 输出如下 域名 com image1 jpg 域名 com image2 jpg 域名 com image3 jpg 我正在尝试随机化输出的顺序 在 foreach 语句之前 我尝试使用 shuffle bb 对数组进行洗牌
  • 创建与 DetailView 相反的视图

    上传图像后 我试图从 CreateView 反转到 DetailView 我收到同样的消息 NoReverseMatch 位于 photo image add 未找到带有参数 和关键字参数 pk 50 的 image view 的反向操作
  • SailsJS Waterline 与 Bluebird Promises

    使用 Waterline ORM 时 如果我想使用默认提供的 bluebird Promise api 如何将处理传递回控制器 下面是代码 module exports Authenticate auth function req res
  • 如何衡量两个数据的相似度

    我正在测量两个大小相同的数据的相似度为20 即 A 0 915450999999999 0 908220499999997 0 900374999999996 0 890547499999996 0 880455499999997 0 86
  • 如何让 Firestore 索引合并发挥作用?

    我在使用 firestore 索引合并来减少所需索引的数量时遇到问题 考虑这个示例情况 Firestore 集合 测试 somedoc a 1 b 1 c 1 d 1 这将导致 Firestore 在测试时为字段 a 到 d 创建 4 个自
  • scala.js 与 jscala 有什么区别?

    有两个工具可以直接在 JavaScript 中编译 Scala 代码 Scala js http www scala js org and JScala https github com nau jscala 它们看起来都很棒 并且可以使用
  • issubclass 的用法

    gt gt gt import sys gt gt gt sys version info 2 4 4 final 0 gt gt gt class C pass gt gt gt issubclass C C True gt gt gt
  • 处理 Akka actor 中的错误

    我有一个非常简单的例子 我有一个演员 SimpleActor 通过向自身发送消息来执行周期性任务 该消息在参与者的构造函数中安排 在正常情况下 即没有故障 一切正常 但如果 Actor 必须处理错误怎么办 我还有另一个演员 SimpleAc
  • 捕获 C++ CLI 应用程序中登录的异常

    我试图捕获 C CLI 应用程序中的所有异常 以便我可以记录它们 包括堆栈跟踪 到目前为止 我有一些看起来很有希望的代码 STAThreadAttribute int main array
  • 使用 cffi-libffi 按值传递结构?

    我的印象是 CFFI 无法按值传递结构 但 CFFI 文档说 要将结构按值传递或返回给函数 请加载 cffi libffi 系统并将结构指定为 struct structure name 要传递或返回指针 您可以使用 pointer or
  • `--oom-kill-disable` 对 Docker 容器有什么作用?

    我已经明白了docker run m 256m memory swap 256m将限制容器 使其最多可以使用 256 MB 内存且无交换区 如果它分配更多 那么容器中的进程 不是 容器 将被杀死 例如 sudo docker run it
  • 在 Javascript 客户端中处理不成功的 websocket 升级请求

    我想让一个 javascript 客户端进程获取当客户端发出 websocket 升级请求并且该请求不成功时服务器返回的 HTTP 状态代码 我的服务器返回 HTTP 400 来指示 Websocket 升级不成功 我正在使用 Google
  • 如何在 WPF 中构建“逐字”自动完成功能?

    我已经做了一些研究 最终得到了几个自动完成框 它们有一个共同点 它们都与已输入的整个表达式匹配 有时 它们看起来很容易扩展 但最终却并非如此 但是 我需要一个文本框 允许用户输入一个单词 例如 tag1 显示一个带有一些建议的弹出窗口基于这
  • URL 路径参数用例

    通常 当我想到 URL 中的参数时 我会想到查询字符串 然而从技术上讲 在路径段中指定参数也是合法的 因此给出一个像这样的 URL http www a com frisbee brand 写成这样是合法的 http www a com f
  • Razor 页面中的 Blazor 组件

    我们有一个基本的剃刀页面应用程序 我们想添加 Blazor 组件 通过复制 04 16 Blazor 更新视频中的步骤或使用 Blazor 文档 我们可以毫无问题地使其发挥作用 但是 一旦我们将 Blazor 组件添加到 Razor 页面
  • ASP.Net / C# - 缺少程序集引用

    Hi I am a newbie in C and visual studio As Figure1 shown I am trying to use the classes from other project in similar so
  • MIPS 中基于指针的数组访问

    MIPS 中基于指针的数组访问是什么意思 基于指针的数组访问 还有一个额外的可能含义或含义 您可能有一个指向数组的指针 而不是位于固定地址的数组 实际上 在 C C 中 指向数组的指针 实际上通常只是指向数组第一个元素的指针 基本上 您有一