MIPS(MARS Simulator)-如何在堆中存储编译时字符串文字

问题描述 投票:0回答:1

[了解了MARS中的.macro后,我决定做一些修改以使我的源代码更具可读性。这样的宏的一个示例是我的str ing len gth宏:

#Gets the length of a string from an address
#Result is in the second operand
#Doesn't count any null-terminators or newlines at the end of the input
#Call example:  strlen MyString,$s0
.macro strlen(%str, %i)
    la $t0,%str
    __strlen_loop:
        lb $t1,0($t0)
        #Exit the loop if this byte is null ('\0') or a newline ('\n')
        beqz $t1,__strlen_end
        beq $t1,'\n',__strlen_end
        inc $t0               #Increment-by-one macro
        j __strlen_loop
    __strlen_end:
    la $t1,%str
    sub %i,$t0,$t1
.end_macro

此宏有效,但是它依赖于预定义的地址才能起作用(%str)。为了尝试解决此问题,我为v alue字符串宏创建了以下str ing len gth:

#Gets the string length of a value string (stores the string in .data)
#Call example:  strlen_v "Hello World!",$s0
.macro strlen_v(%str,%i)
    #Create a label for the string
    .data
    __strlen_v_label: .asciiz %str
    .text
    #Get the length
    strlen __strlen_v_label,%i
.end_macro

不幸的是,还有另一个问题。第二个宏将值字符串存储在.data中,该字符串仅具有0x30000个字的空间(地址0x10010000至地址0x10040000)。最好将值字符串存储在heap上,因为它具有更多的空间and我将能够更有效地管理内存。


是否可以使用.data将编译时值字符串存储在堆上[[without”?我发现的唯一示例是用户输入的字符串和已经存储在.data中的字符串,但这两个都不适用于此问题。

string macros mips
1个回答
0
投票

是否可以在不使用.data的情况下在堆上存储编译时值字符串?

不是。根据定义,堆在概念上在程序启动时为空。而且,根据定义,字符串文字是在数据部分中初始化的常量。您只能在运行时分配堆空间,而不能在编译时分配堆空间。因此,在运行时,您可以分配堆空间并将字符串从文字数据移动到堆...


但是,请注意,MARS和QtSPIM允许为.data提供参数,这是放置后续内容的位置。例如,我们可以执行.data 0x10040000,这将导致随后的字符串文字放置在该位置。但是,这将干扰正常的堆操作,因为您的第一个sbrk syscall仍将返回0x10040000,这是使用.data 0x10040000放置在其中的字符串文字所占用的内存,因为sbrk syscall并不知道该指令。


从长远来看,将字符串长度定义为函数而不是宏可能会更符合您的期望:

  • 您可以确定字符串文字,本地字符串或基于堆的字符串的长度,
  • 您的注册约定将属于常规的调用约定(不确定甚至没有宏约定),
  • 您将把字符串常量声明与字符串长度操作分开。
© www.soinside.com 2019 - 2024. All rights reserved.