我正在编写一个小编译器,我无法处理字符串常量和字符串对象。
以下面的代码为例:
s : String = "Hello world"
由于字符串在程序中,编译器将识别该字符串,并生成字符串常量并将其放在.data
段中。
.data
string_const1:
.quad 2
.quad 6
.quad String_dispatch_table
.quad int_const1
.asciz "Hello world"
.align 8
然后可以通过以下方式访问实际的字符串:
leaq string_const1(%rip), %rax
addq $32, %rax
但是,如果我们要求用户输入字符串,则需要动态生成字符串对象。以下是字符串对象模板,该模板也放置在.data
段中。
String_protoObj:
.quad 2 # tag
.quad 5 # size
.quad String_dispatch_table
.quad 0 # string length
.quad 0 # string content
# assume %rax contains the address of a copy of String_protoObj
# assume %rdi contains the address of user input string
leaq String_protoObj(%rip), %rdi
callq malloc
movq user-input, %rdi
movq %rdi, 32(%rax) # copy the new string into string content
然后稍后访问实际的字符串,我必须使用
32(%rax) # read from memory
因此,从字符串常量访问字符串和动态分配的字符串对象之间存在差异,这需要在所有函数中使用不同的句柄
我显然可以在protoObject中添加另一个标记来指示这是一个已分配的对象而不是一个常量,但这需要接收字符串对象/常量的所有方法进行检查,这听起来并不优雅。 / p>
任何人都可以给我任何关于如何处理这种情况的建议吗?
答案 0 :(得分:1)
就个人而言,我首先使常量看起来像一个字符串对象,这意味着第五个字将包含指向第六个字的指针。这是你明显愿意用字符串对象支付的价格。
更节省空间的策略是大多数现代C ++库使用的策略,其中有两个字符串布局:一个包含字符向量(短字符串),另一个带指针。你可以告诉他们除了长度,所以你不需要一个不同的标签,但当然你也可以使用不同的标签。
在实践中,大多数字符串都相当短,因此这种优化被认为是有用的。但是它的工作量更大,而且要编写更多测试,因此您可能希望将其保存以供日后使用。