【问题标题】:Edit memory address of an initialized .data segment word in MIPS在 MIPS 中编辑已初始化的 .data 段字的内存地址
【发布时间】:2017-12-19 00:38:30
【问题描述】:

像这样在 .data 段中初始化一个单词后:

.data
base: .word 0

我需要在 .text 段内更改保存“base”的地址。例如,如果'base'存储在地址'268501692'中,我需要将其更改为'268501700'

我该怎么做?

【问题讨论】:

  • 您无法重命名/重新寻址内存单元地址,因此不清楚您真正想要什么。 base 只是内存地址的符号名称,一旦为 1234,即为 1234。如果您想要地址 2345,则使用 2345。
  • 我想重新寻址该符号名称指向的位置。这不是不可能的吗?
  • 不,它是编译时常量,如果你在运行时执行la $1,symbol,它已经是指令机器代码中的固定值(运行时没有“符号”名称/字符串)。汇编程序中不存在这种解决方案(无论您的原始问题是什么)。您可以在运行时自行修改指令操作码以更改值(从 1234 到 2345),但现在这被认为是“代码异味”,很可能您的原始问题有不同的常见解决方案模式.
  • 我基本上想通过syscall 9分配内存,并将v0的地址(这是分配的地址空间的基数)写入.data段标签,之后也可以对其进行操作.
  • 我明白了,这是间接的。您将v0 存储到某个固定位置,例如base,即sw $v0,base,然后在将广泛使用该分配内存的代码之前,将地址加载到一些备用寄存器(例如lw $t6,base)中,然后通过寻址t6 一切,如lw $t0,16($t6) 将从t6+16 地址加载字。 (并且base: .word 0 用作指针存储,而不是数据存储)然后您还可以轻松地推进寄存器中的值,例如addi $t6,$t6,140 推进到下一个元素,如果分配的内存是某种具有 140B 大小的元素数组。

标签: assembly mips mips32


【解决方案1】:

来自您的评论:

我基本上想通过syscall 9分配内存,并将v0的地址(这是分配的地址空间的基数)写入.data段标记,并且之后也能够对其进行操作。

在 C 语言中,您的要求是修改static int array[] 的地址以将其设置为malloc 的返回值。

符号不是这样工作的。当您组装和链接时,它们成为固定的数字地址。 lw $t0, base($zero) 运行时不会发生符号表查找:机器代码指令将地址硬编码为立即常数。见a MIPS ISA reference for the encoding format


您应该做的是将该指针存储在寄存器中,或存储在固定的内存位置,即static int *pointer。那么你只需要修改指针的value,它还是有自己的地址的。这是对静态数组的额外间接级别,但前提是您将指针保存在内存中。使用寄存器中的指针,它是指向静态数组还是动态分配的内存都没有关系。

不要让 C 语法欺骗你:pointer[10] 看起来与 array[10] 相同,但在指针情况下(使用 static 或全局 pointer 变量),编译器必须首先发出 asm从内存中加载指针,然后取消引用它。但是在数组的情况下,array的地址是一个链接时间常数,所以编译器可以直接访问array[10],因为那也是一个链接时间常数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多