MIPS 在程序中使用 $s0... 等注册并最终恢复它是否优雅

2024-04-22

我在 MIPS 教程中读到,只有寄存器 $s0-$s7 在过程调用中被保留。 但我认为(也许我错了?)创建有副作用的程序并不优雅 - 我认为程序应该只更改 $v0、$v1 寄存器和堆栈(如果需要的话)(我是对的吗?)。 所以我认为在我的程序中我只能使用 $t0-$t9 寄存器。 但是当我在程序中调用一些过程时,它可以更改 $t0-$t9 寄存器。所以我必须存储临时寄存器并在程序中的过程调用后恢复它。但是当我的程序如下所示时:

call procedure1
compute something on temporary reginsters

call procedure2
compute something on temporary reginsters

call procedure3
compute something on temporary reginsters

...

我的程序需要大量的内存访问。 所以我的想法是使用:

Store at the begining of my procedure reginsters $s0-$s7.
Use reginsters $s0-$s7 in my procedure.
Restore old values of reginsters $s0-$s7.

它优雅吗?有什么不好的后果吗?


我在 MIPS 教程中读到,只有寄存器 $s0-$s7 在过程调用中被保留。

没有什么神奇的事情发生$s0-$s7整个通话过程中(例如jal some_routine只需将返回地址粘贴到$ra并跳转到some_routine;没有其他事情发生)。

在调用过程中保存这些寄存器只是一种约定:它是标准“应用程序二进制接口”(ABI) 的一部分,这是一组涵盖寄存器使用、堆栈使用、数据格式等的约定。 -- 不同的代码位符合相同 ABI 的应用程序(应用程序、库等)将能够相互操作。

如果您希望您的代码可以从其他地方调用,您的代码需要符合调用者期望的 ABI。例如如果您正在编写一些需要从 C 代码调用的汇编例程,则需要符合 C 编译器生成的代码所使用的 ABI。

对于通常的 MIPS ABI,这意味着调用例程的代码将假定它输入的任何值$s0 - $s7在调用之前仍然会在调用返回之后,但它会not假设内容$t0 - $t9还是一样。 (类似地,如果您的代码调用库例程(例如),它可以做出相同的假设:调用返回后,任何在$s0 - $s7已被保留,但是$t0 - $t9可能包含任何东西。)

这意味着您的代码必须保存以下任何内容$s0 - $s7在更改它们之前,并在返回之前恢复它们。保存和恢复它们之间的作用并不重要——重要的是调用者看不到任何变化。

所以,是的,你的想法是正确的(实际上也是明智的做法)。

(请注意,您的子程序(procedure1, prodcedure2 etc.) 不一定必须符合此标准 ABI,if它们仅从您的主过程中调用,并且不会调用外部例程 - 因为在这种情况下,它们只需要与您的主过程进行互操作,而不需要与任何其他代码进行互操作。但无论如何,遵循 ABI 都是一个好主意,除非有充分的理由不这样做;它使得更容易阅读代码,更容易在必要时使内部过程之一更加公开,更容易添加对其他代码的调用,等等)

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

MIPS 在程序中使用 $s0... 等注册并最终恢复它是否优雅 的相关文章

  • 如何在 AVX/AVX2 中递增向量

    我想使用内在函数来增加 SIMD 向量的元素 最简单的方法似乎是为每个元素加 1 如下所示 note vec inc之前已设置为1 vec mm256 add epi16 vec vec inc 但是是否有任何特殊指令来增加向量 类似于in
  • 将代码保存在 L1 缓存中

    我一直在阅读维基百科关于 K 编程语言的文章 http en wikipedia org wiki K programming language Performance characteristics这就是我所看到的 解释器的小尺寸和语言的
  • 为什么这个函数在额外读取内存时运行速度如此之快?

    我目前正在尝试了解 x86 64 上某些循环的性能属性 特别是我的 Intel R Core TM i3 8145U CPU 2 10GHz 处理器 具体来说 在循环体内添加一条额外的指令来读取内存几乎可以使性能提高一倍 而细节并不是特别重
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • 英特尔 JCC 勘误表 - 用于缓解的前缀有什么影响?

    Intel 推荐 https www intel com content dam support us en documents processors mitigations jump conditional code erratum pd
  • 电路解码所需的最小输入位数

    我正在学习计算机体系结构 并且正在阅读有关编码器和解码器的内容 在 MIPS 处理器中 操作码有 6 位 我想知道构建解码器来解码操作码需要多少输入位 我知道解码器是一个组合电路 它将二进制信息从 n 个输入线转换为最多 2 n 个唯一的输
  • GCC 内联 asm NOP 循环在编译时未展开

    走出我通常的 VC 领域 进入 GCC 的世界 通过 MINGW32 尝试创建一个主要由 NOP 组成的 Windows PE ala for i 0 i lt 1000 i asm nop 但要么我使用了错误的语法 要么编译器正在通过它们
  • 编写一个新的 jit

    我有兴趣用 C 启动我自己的 JIT 项目 我对汇编或编译器设计等并不熟悉 但是 我对生成的机器代码格式非常不熟悉 比如 当一切都说了和完成后 mov 指令实际上是什么样子 是时候调用它了函数指针 那么 创建这样的东西的最佳资源是什么 编辑
  • x86 汇编乘法和除法指令操作数,16 位及更高

    我对 x86 汇编中的乘法和除法运算如何工作感到相当困惑 例如 下面的代码看起来并不太困难 因为处理的是 8 位 8 位乘法 User Input num1 20 num2 15 mov ax num1 moves the 8 bits i
  • 如何使用存储在 x64 位置的 x64 内存地址进行跳转?

    据我所知 使用 64 位地址作为操作数的 jmp 是不可能的 但我相信使用 x64 内存位置是 来自here http www tptp cc mirrors siyobik info instruction JMP htmlJMP r m
  • 给寄存器赋值并加减

    我对此完全迷失了 我需要使用寄存器来计算以下表达式的编程 varA varA varB varC varD 其中 varA varB 等是变量 将整数值分配给上述变量的 EAX EBX ECX 和 EDX 寄存器 这意味着 您可以对输入进行
  • MAC-1 汇编递归

    如何在 MAC 1 汇编器中调用递归函数 在 C 中你会做类似的事情 int func int num if num 0 return 1 return num func num 1 我知道如何使用调用函数 CALL 以及如何将参数加载到堆
  • RISC-V反汇编器与秒杀运行结果不符?

    我已经设置了一个 hello world 程序只是为了测试我的riscv32 unknown elf工具链 spike pk等等虽然我设法使用打印了 hello worldspike isa RV32 pk hello elf 我发现如果我
  • 是否可以调用驻留在 exe 中的非导出函数?

    我想调用驻留在第 3 方 exe 中的函数并获取其结果 好像有should是一种方法 只要我知道函数地址 调用约定等 但我不知道如何 有谁知道我会怎么做 我意识到任何解决方案都是非标准的黑客 但有must成为一种方式 我的非恶意用例 我正在
  • 简单内核无法在 GRUB 中启动

    我正在学习一些操作系统开发的知识OSDev org http osdev org 我有一个内核 我正在尝试使用 qemu 在 GRUB Legacy 0 97 中启动 但是 当我输入kernel 200 9 我收到消息 Multiboot
  • (nasm x86实模式)如何在引导加载的扇区中写入/读取字符串?

    我正在使用 NASM 为 x86 实模式编写一个最小操作系统 用于教育目的 我想使用 512 字节引导扇区加载包含操作系统其余部分的更大扇区 我已经成功创建了一个加载另一个扇区的引导扇区 但我似乎无法在加载的扇区中写入 读取字符串 这是我的
  • 尝试理解 printf() 的 gcc 汇编输出

    我正在尝试学习如何理解汇编代码 因此我一直在研究 GCC 的汇编输出以获取一些愚蠢的程序 其中之一只不过是int i 0 我现在或多或少完全理解了其中的代码 最大的困难是理解散布的 GAS 指令 无论如何 我向前迈了一步并添加了printf
  • 是否有必要每个机器码只能映射到一个汇编代码?

    假设这两者本质上是相同的 push 1 and 0x1231 这表示每个汇编指令都映射到一个机器代码 但是否每个机器码只能映射到一个汇编代码呢 MIPS汇编语言有几个 伪指令 例如 move 在内部只是一个带有隐式 0 操作数的 add
  • 将 1 字节立即值添加到 2 字节内存位置

    The add说明文档来 自这一页 http x86 renejeschke de html file module x86 id 5 html说如下 请注意我突出显示的两条说明 我在 NASM 中尝试了以下代码 符合第一个突出显示的指令
  • 基于 MIPS 的 codesourcery 工具链的编译参数?

    我在我的 WIN 7 机器上安装了用于 mips32 架构的 codesourcery 交叉编译工具链 我想首先为我的路由器编译一个基于 MIPS32 的简单 阶乘 二进制文件 在网上搜索了一下 我发现它是基于MIPS32 big endi

随机推荐

  • “parse”在交互和非交互模式下的行为不同

    我认为这可能是一个错误parse 但想检查一下是否还有其他人有更好的主意 在交互模式 RStudio 下 以下代码可以正常工作 txt lt c c integer 3L 1 3 c integer 1 3 1L TRUE c intege
  • 用颤动绘制虚线弧

    Flutter 有没有办法画虚线弧 目前我正在使用 canvas drawArc 但我不知道如何获得正确的结果 canvas drawArc rectangle startAngle fullArcRadius false Paint co
  • 带有 pfx 文件的 Azure https

    我正在尝试创建一个https我的天蓝色服务的端点 我被给予了p7b我转换成的文件cer文件 来自cer我能够用几行 c 转换为pfx var cert new X509Certificate2 certpath var bytes cert
  • 返回 clickhouse 数组作为列

    Clickhouse 是否可以将包含一对数组的结果转换为列 形成这个结果 f1 f2 f3 a 1 2 3 x y z b 4 5 6 x y z to f1 x y z a 1 2 3 b 4 5 6 这个想法是不必为每行重复标题值 就我
  • Webpack - 如何捆绑/需要文件夹(子文件夹)的所有文件

    我想看看是否有更短的方式来运行 webpack 包 以及为什么我的加载器不起作用 这是我的代码 module exports context path join dirname dist entry ES6bundle js jQuery
  • JS 库来模拟 Internet Explorer?

    Webkit中有一些JS库可以模拟IE吗 例如 IE8不支持border radius目前 可能在 IE10 上 所以我运行一个 JS 库来检查我是否正在使用border radius然后将其删除以制作类似于IE的视觉 我知道这是一个疯狂的
  • Android Accessibility 服务实时音频处理

    有人可以为我提供 Android 辅助功能服务实时音频处理的示例代码吗 我需要处理通话音频 但不知道如何实现这一点 请分享您对此的想法 请找到下面的清单
  • 我如何在create js中更改图形的填充颜色

    我用它来改变创建js中的填充颜色 这不起作用 var shape rect new createjs Shape shape rect graphics beginFill FFD64B drawRect 61 253 398 25 sha
  • 检查混音器线路中的音频播放电平?

    我试图弄清楚 Windows 中是否正在播放任何类型的声音 通过任何应用程序 如果某处有什么东西发出噪音 我想知道 在遵循文档之后 我找到了如何获取机器上的混音器列表以及这些混音器的线路 如果我理解正确的话 这些线路是用于混音器的输入 输出
  • 如何设置选择器的边框

    我有来自 反应本机 Picker Item有 周一 周二 周三等 我想设置选择器的属性 例如borderRadius 10 even style borderRadius 30 没有帮助
  • CSS3 使文本在三角形内居中

    我在页面的左上角有一个三角形图像 以及一些需要在底部居中的文本 使用 CSS3transform rotate 我可以通过一些定位 边距来做到这一点 但它在浏览器中看起来并不相同 它看起来有点向左或向右 有没有办法将其居中 以便它在所有浏览
  • FindFirstFile 和 FindNextFile 问题

    输出 The first file found is LOG 09 TXT Next file name is LOG 10 TXT Next file name is LOG 11 TXT Next fi cut off word fil
  • 当文件名有重音符号时使用 pandas.read_csv 进行编码

    我正在尝试使用 pandas 加载 CSV 但如果文件名有重音符号 则会遇到问题 这显然是一个编码问题 但尽管如此read csv允许您设置文件内文本的编码 我不知道如何正确编码文件名 input file r C Datasets s P
  • 我应该用 C++ 封装 Lua 代码的哪些代码?

    我终于将 LuaBind 配置为与我的 C 项目一起使用 我最近发现 Tiled 地图编辑器可以选择将文件导出为 lua 所以我想尝试一下 我将使用什么代码来封装下面粘贴的代码以使其与我的 C RPG 项目一起使用 return versi
  • 空 Repeater 控件的默认文本

    使用 VS 2008 我有一个 Repeater 控件
  • GPUImage 的 GPUImageOpacityFilter 行为不符合预期,不会更改 Alpha 通道

    我正在尝试做一个Overlay Blend具有相机源输出的库存图像 其中库存图像的不透明度小于 100 我想我可以放一个GPUImageOpacityFilter在过滤器堆栈中 一切都会好起来的 GPUImageVideoCamera gt
  • DOM 元素的样式对象更改后可以触发 JavaScript 钩子吗?

    一个元素有一个 JavaScriptstyle包含 CSS 样式的不同名称和值的对象 我想在每次该对象发生变化时触发一个函数不使用轮询 有没有什么方法可以跨浏览器兼容并且可以与第三方代码可靠地工作 因为假设您提供了一个嵌入式脚本 绑定 Ja
  • 从 WebBrowser 控件以横向模式打印?

    System Windows Forms WebBrowser wb new System Windows Forms WebBrowser wb DocumentStream new FileStream C a html FileMod
  • 自定义组件和选项卡顺序

    我有一个自定义组件 继承自TCustomPanel 由另外两个组件组成 假设有两个编辑 使用组件时如何获得正确的 Tab 键顺序 在选项卡顺序设计器中 我只能访问组件本身 该组件本身无法获得焦点 因为它是一个面板 在运行时发生的情况是 我可
  • MIPS 在程序中使用 $s0... 等注册并最终恢复它是否优雅

    我在 MIPS 教程中读到 只有寄存器 s0 s7 在过程调用中被保留 但我认为 也许我错了 创建有副作用的程序并不优雅 我认为程序应该只更改 v0 v1 寄存器和堆栈 如果需要的话 我是对的吗 所以我认为在我的程序中我只能使用 t0 t9